/* ============================================================================
   Kaycie — dashboard & forms design system (CURRENT: v9.5, 2026-07-11).
   From Core 0.5.74 this file SHIPS INSIDE THE PLUGIN (assets/kaycie-dashboard.css,
   enqueued site-wide) — once a site runs 0.5.74, DELETE its FluentSnippets CSS
   snippet; updates arrive with the plugin from then on.

     v3  base: brand-styled forms everywhere, .kc-powered footnote, a11y fixes
     v4  collapsible .kc-fold sections + per-page .kc-howto pill
     v5  flow section headers (.kc-sec-head) + notification-row polish
     v6  .kc-next pill row — dashboard cross-links, coloured by destination flow
     v7  ID-picker dropdowns (.kc-picked, .kc-pickform) + mobile polish
     v8  type-ahead search (.kc-pick-search), [kc_list] search, .kc-update cards
     v9  THE REDESIGN (from design's standalone mock, 2026-07-10):
         Mulish body + Hanken Grotesk display · warmer canvas #fbf6f3 ·
         16-18px card radii with soft deep shadows + hover lift · uppercase
         eyebrow section heads with tinted icon chips + hairline rule ·
         stat tiles left-aligned, label above an ink 800 number · gold
         pulse-dot fold headers · wine pill counts · gold-tinted How-to pill ·
         soft ghost buttons · dark ink hero utility (.kc-dark-card).
         Same class names throughout — NO dashboard re-pastes needed.
     v9.3 mobile buttons keep natural size (only JFB submits go full-width) ·
         icon row-actions (.kc-iconbtn 34px ghost square) + .kc-key legend
         under tables · notifications Mark-read is an icon-only tick.
   ============================================================================ */

@import url('https://fonts.googleapis.com/css2?family=Hanken+Grotesk:wght@400;500;600;700;800&family=Mulish:wght@400;500;600;700&display=swap');

:root {
  --kc-ink:        #2d0213;
  --kc-primary:    #7c0a27;
  --kc-primary-dk: #51031b;
  --kc-gold:       #e0a23c;
  --kc-gold-dk:    #d4941f;
  --kc-gold-text:  #a86a12;              /* readable gold for text on cream/white */
  --kc-gold-pale:  #f0cf95;
  /* the brand as an RGB triplet, for every translucent use (focus rings, badge tints, the
     notify pulse). These were hard-coded rgba(124,10,39,…) — no colour picker could reach
     them, so a re-branded tenant still glowed kaycie wine round every focused field.
     KC_Dashboards::brand_css() overrides this alongside --kc-primary. */
  --kc-primary-rgb: 124,10,39;
  --kc-green:      #4E8C6A;
  --kc-clay:       #CF6A4D;              /* the mascot's clay (Zina 2026-07-18: "the missing clay
                                            colour") — canonised from the error bubble. NOTE: the
                                            bubble SVGs are data-URIs and cannot read CSS vars, so
                                            they carry this hex literally — keep them in sync. */
  --kc-muted:      #6b4a4f;
  --kc-muted-2:    #9a7b76;
  --kc-muted-3:    #b89a94;
  --kc-rose:       #c98f99;              /* eyebrows on cream, muted text on ink */
  --kc-line:       #efe1dc;              /* card borders */
  --kc-line-mid:   #e7d6d0;              /* ghost-button borders, dividers */
  --kc-line-soft:  #f6ece8;              /* row hairlines */
  --kc-line-head:  #f3e4e0;              /* panel header underline */
  --kc-bg:         #fbf6f3;
  --kc-bg-tint:    #fdf6f3;              /* hover / header gradient end */
  --kc-card:       #ffffff;
  --kc-soft:       #f6e7e3;              /* pink icon chips */
  --kc-radius:     16px;
  --kc-radius-lg:  18px;
  --kc-radius-btn: 10px;
  --kc-shadow:     0 1px 2px rgba(45,2,19,.05);
  --kc-shadow-lift:0 14px 34px -18px rgba(45,2,19,.28);
  --kc-shadow-deep:0 14px 40px -22px rgba(45,2,19,.28);
  --kc-font:       'Mulish', -apple-system, BlinkMacSystemFont, sans-serif;
  --kc-font-head:  'Hanken Grotesk', -apple-system, BlinkMacSystemFont, sans-serif;
}

/* ---------- dashboard layout ---------- */
.kc-dash            { max-width: 1140px; margin: 0 auto; padding: 1.9rem 1rem 2rem; color: var(--kc-ink); font-family: var(--kc-font); }
.kc-dash h1         { font-family: var(--kc-font-head); font-size: clamp(1.85rem, 3.4vw, 2.4rem); font-weight: 800;
                      letter-spacing: -0.025em; line-height: 1.06; margin: 0 0 .3rem; color: var(--kc-ink);
                      width: fit-content; max-width: 100%; }
/* v9: the gold underline retires — the display type IS the header now */
.kc-dash h1::after  { display: none; }
.kc-dash .kc-sub    { color: var(--kc-muted); margin: .35rem 0 1.6rem; font-size: 1rem; line-height: 1.55; max-width: 560px; }
/* min(100%,…) so a column never exceeds the container -> no horizontal overflow on narrow phones */
.kc-grid            { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); gap: 1.1rem; }
/* stat rows pack tighter: 2-up on mobile, up to 4-up on desktop (no HTML change needed) */
.kc-grid:has(.kc-stat) { grid-template-columns: repeat(auto-fit, minmax(min(100%, 165px), 1fr)); }
.kc-dash-actions    { display: flex; flex-wrap: wrap; gap: .5rem; margin: 0 0 1.4rem; align-items: center; }
/* v9.5 — back-to-Home link injected on every dashboard except Home */
.kc-backhome        { display: inline-flex; align-items: center; gap: .35rem; font-family: var(--kc-font);
                      font-weight: 700; font-size: .82rem; color: var(--kc-muted); text-decoration: none; margin: 0 0 1rem; }
.kc-backhome:hover  { color: var(--kc-primary); }

/* ---------- cards ---------- */
.kc-card            { background: var(--kc-card); border: 1px solid var(--kc-line); border-radius: var(--kc-radius);
                      box-shadow: var(--kc-shadow); padding: 1.35rem 1.4rem; margin: 0 0 1.15rem;
                      transition: box-shadow .16s ease, transform .16s ease, border-color .16s ease; }
.kc-grid > .kc-card       { display: flex; flex-direction: column; margin: 0; }
.kc-grid > .kc-card:hover { box-shadow: var(--kc-shadow-lift); transform: translateY(-2px); border-color: var(--kc-line-mid); }
.kc-card > h2, .kc-card > h3 { margin: 0 0 .5rem; font-family: var(--kc-font-head); font-size: 1.08rem; font-weight: 700; color: var(--kc-ink); letter-spacing: -0.01em; }
.kc-card .kc-card-note { color: var(--kc-muted); font-size: .87rem; line-height: 1.5; margin: -.15rem 0 1rem; }
/* home launcher cards: the note takes the stretch, the Open button reads as a wine link */
.kc-grid > .kc-card > .kc-card-note { flex: 1; }
.kc-grid > .kc-card > .kc-btn-ghost:last-child {
  border: 0; background: none; padding: 0; align-self: flex-start;
  color: var(--kc-primary); font-weight: 700; font-size: .9rem; border-radius: 0;
}
.kc-grid > .kc-card > .kc-btn-ghost:last-child::after { content: " \2192"; }
.kc-grid > .kc-card > .kc-btn-ghost:last-child:hover { background: none; color: var(--kc-primary-dk); }

/* stat tiles (headline numbers) — v9.2 (design's fix): NATURAL top-to-bottom order,
   markup written label → number → delta. (v9's column-reverse only worked for two
   children — a delta line made three and the order inverted.)
   .kc-card.kc-stat so it outweighs the .kc-grid > .kc-card rule. */
.kc-card.kc-stat    { display: flex; flex-direction: column; justify-content: flex-start;
                      text-align: left; border-top: 0; padding: 1.05rem 1.2rem; }
.kc-stat .kc-num    { font-family: var(--kc-font-head); font-size: 1.85rem; font-weight: 800;
                      letter-spacing: -0.02em; color: var(--kc-ink); line-height: 1.1; margin: 0; }
.kc-stat .kc-label  { font-family: var(--kc-font-head); color: var(--kc-muted-2); font-size: .69rem; font-weight: 700;
                      text-transform: uppercase; letter-spacing: .08em; margin: 0 0 .35rem; }

/* ---------- [kc_list] tables ---------- */
.kc-list            { width: 100%; border-collapse: collapse; font-size: .9rem; color: var(--kc-ink); }
.kc-list-wrap       { overflow-x: auto; }
.kc-list thead th   { text-align: left; font-family: var(--kc-font-head); font-weight: 700; color: var(--kc-muted-2);
                      font-size: .7rem; text-transform: uppercase; letter-spacing: .07em; padding: .6rem .75rem;
                      border-bottom: 1px solid var(--kc-line-head); white-space: nowrap; }
.kc-list tbody td   { padding: .72rem .75rem; border-bottom: 1px solid var(--kc-line-soft); vertical-align: top;
                      overflow-wrap: anywhere; }  /* long emails/URLs wrap so the table fits — no slider */
.kc-list tbody tr:hover td { background: var(--kc-bg-tint); }
.kc-list-empty      { color: var(--kc-muted-2); font-size: .92rem; padding: .5rem 0; }

/* the notification deep-link focus row ([kc_list] ?kcfocus=) keeps its gold ring via inline style */

/* status pills */
.kc-badge           { display: inline-block; padding: .14rem .62rem; border-radius: 999px;
                      font-family: var(--kc-font-head); font-size: .72rem; font-weight: 700; letter-spacing: .02em; }
.kc-badge-active,.kc-badge-approved,.kc-badge-complete,.kc-badge-granted { background: rgba(78,140,106,.14); color: #2f6b4d; }
.kc-badge-pending,.kc-badge-grace,.kc-badge-requested { background: rgba(224,162,60,.16); color: var(--kc-gold-text); }
.kc-badge-rejected,.kc-badge-void,.kc-badge-suspended { background: #f6e0e2; color: var(--kc-primary); }

/* the second line on a stat tile — the annual figure under a monthly one, or what is
   still needed under a percentage (2026-08-18). Quieter than the label, never competes. */
.kc-stat-sub        { margin-top: .3rem; font-size: .78rem; line-height: 1.35; color: var(--kc-muted-2); }

/* ---------- buttons ---------- */
.kc-btn, .kc-payfast-settings button, .jet-form-builder button[type=submit] {
  display: inline-block; background: var(--kc-primary); color: #fcf7f4; border: 0; cursor: pointer;
  padding: .68rem 1.35rem; border-radius: var(--kc-radius-btn); font-weight: 700; font-size: .92rem; text-decoration: none;
  font-family: var(--kc-font); box-sizing: border-box; transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.kc-btn:hover, .jet-form-builder button[type=submit]:hover, .kc-payfast-settings button:hover { background: var(--kc-primary-dk); color: #fcf7f4; }
.kc-btn-gold        { background: var(--kc-gold); color: var(--kc-ink); }
.kc-btn-gold:hover  { background: var(--kc-gold-dk); color: var(--kc-ink); }
/* v9 ghost: soft neutral border + wine text (the design's quiet secondary button) */
.kc-btn-ghost       { background: transparent; color: var(--kc-primary); border: 1px solid var(--kc-line-mid); font-weight: 700; }
/* a11y: hover keeps full contrast — wine fill, cream text */
.kc-btn-ghost:hover { background: var(--kc-primary); color: #fcf7f4; border-color: var(--kc-primary); }
/* Zina 2026-07-13: a clicked/focused action button must never repaint dark ("goes black on
   select"). Pin :active like hover, give keyboard focus a clean ring, kill the mobile tap-flash. */
.kc-btn:active, .jet-form-builder button[type=submit]:active, .kc-payfast-settings button:active { background: var(--kc-primary-dk); color: #fcf7f4; }
.kc-btn-gold:active { background: var(--kc-gold-dk); color: var(--kc-ink); }
.kc-btn-ghost:active { background: var(--kc-primary); color: #fcf7f4; border-color: var(--kc-primary); }
.kc-btn, .kc-btn-ghost, .kc-btn-gold, .kc-kebab-btn, .kc-iconbtn { -webkit-tap-highlight-color: transparent; }
.kc-btn:focus-visible, .kc-btn-ghost:focus-visible, .kc-btn-gold:focus-visible,
.kc-kebab-btn:focus-visible, .kc-iconbtn:focus-visible { outline: 2px solid var(--kc-primary); outline-offset: 2px; }
/* greyed, non-clickable action button — e.g. "Issue 18A" while a gate isn't met; the title says why */
.kc-btn-off, .kc-btn-off:hover, .kc-btn[disabled], .kc-btn[disabled]:hover {
  background: var(--kc-line-mid, #e7d6d0); color: var(--kc-muted); border-color: var(--kc-line-mid, #e7d6d0);
  cursor: not-allowed; box-shadow: none; opacity: .9;
}

/* ---------- forms (GLOBAL — every JetFormBuilder form, public + dashboard) ---------- */
/* v9.4 (Zina: "blank lines at the bottom of the forms"): rows holding ONLY hidden fields
   (honeypot, timing cookie, seeded defaults) still took their full row margin. Collapse
   any JFB row/wrap with no visible control, and the last row's trailing margin. */
.jet-form-builder-row:not(:has(input:not([type=hidden]), select, textarea, button, .jet-form-builder__label, p, img)),
.jet-form-builder__field-wrap:not(:has(input:not([type=hidden]), select, textarea, button, label, p, img)) {
  display: none; margin: 0; padding: 0;
}
/* v9.5 (Zina: "Add a beneficiary form STILL has blank lines"): the :has() rule above
   depends on guessing JFB's wrapper class. JFB reliably tags a hidden field's own
   wrapper with .field-type-hidden-field — hide THAT directly, plus any empty block the
   form content leaves behind. This does not depend on the wrapper class matching. */
.jet-form-builder .field-type-hidden-field,
.jet-form-builder__field-wrap.field-type-hidden-field,
.jet-form-builder-row.field-type-hidden-field,
.jet-form-builder [data-field-type="hidden-field"],
.jet-form-builder input[type=hidden] + br,
.jet-form-builder p:empty, .jet-form-builder br:only-child { display: none !important; margin: 0 !important; padding: 0 !important; }
.jet-form-builder > *:last-child { margin-bottom: 0; }
.kc-fold-body > p:empty, .kc-fold-body br:only-child { display: none; }
.kc-fold-body > *:last-child { margin-bottom: 0; }

/* v9.5 — buttons-only reveal (Zina: docs 2d / programmes P5 / donor D5 — a button that
   sits ABOVE an accordion whose summary repeats the label reads as a duplicate heading).
   Add .kc-fold-quiet to a fold and its summary bar disappears; the kc-jump button becomes
   the only trigger (the chrome footer script TOGGLES it). No duplicate label, form on press. */
.kc-fold.kc-fold-quiet > summary { display: none; }
.kc-fold.kc-fold-quiet[open]   { margin-top: .25rem; }
.kc-fold.kc-fold-quiet[open] > .kc-fold-body { border: 1px solid var(--kc-line); border-radius: 14px; }
.jet-form-builder                 { max-width: 40rem; font-family: var(--kc-font); }
.jet-form-builder__field-wrap     { margin-bottom: 1.15rem; }
.jet-form-builder__label,
.jet-form-builder label.jet-form-builder__label {
  font-weight: 700; font-size: .9rem; margin-bottom: .35rem; display: block; color: var(--kc-ink);
}
.jet-form-builder input[type=text], .jet-form-builder input[type=email], .jet-form-builder input[type=tel],
.jet-form-builder input[type=number], .jet-form-builder input[type=date], .jet-form-builder input[type=password],
.jet-form-builder input[type=url], .jet-form-builder select, .jet-form-builder textarea, .kc-payfast-settings input {
  width: 100%; padding: .65rem .85rem; border: 1px solid var(--kc-line); border-radius: var(--kc-radius-btn);
  font-size: .95rem; background: #fff; color: var(--kc-ink); box-sizing: border-box; font-family: var(--kc-font);
  transition: border-color .12s ease, box-shadow .12s ease;
}
.jet-form-builder input:focus, .jet-form-builder select:focus, .jet-form-builder textarea:focus,
.kc-payfast-settings input:focus { outline: none; border-color: var(--kc-primary); box-shadow: 0 0 0 3px rgba(var(--kc-primary-rgb),.12); }
.jet-form-builder__desc           { color: var(--kc-muted); font-size: .83rem; margin-top: .3rem; }
.jet-form-builder__required-mark  { color: var(--kc-primary); }
.jet-form-builder__fields-group label, .jet-form-builder .checkbox-wrap label {
  font-weight: 400; display: flex; gap: .5rem; align-items: flex-start; margin: .3rem 0;
}
.jet-form-builder__field-error    { color: var(--kc-primary); font-size: .85rem; margin-top: .25rem; }
.jet-form-builder-message--success { background: rgba(78,140,106,.12); border: 1px solid rgba(78,140,106,.3); color: #2f6b4d; padding: .8rem 1rem; border-radius: var(--kc-radius-btn); }
.jet-form-builder-message--error   { background: #f6e0e2; border: 1px solid #efc9cd; color: var(--kc-primary); padding: .8rem 1rem; border-radius: var(--kc-radius-btn); }

/* ---------- notices / state panels ---------- */
.kc-notice          { padding: .72rem 1rem; border-radius: var(--kc-radius-btn); margin: 0 0 1rem; font-size: .92rem; }
.kc-notice.kc-ok    { background: rgba(78,140,106,.12); color: #2f6b4d; border: 1px solid rgba(78,140,106,.3); }
.kc-notice.kc-err   { background: #f6e0e2; color: var(--kc-primary); border: 1px solid #efc9cd; }
.kc-notice.kc-warn  { background: rgba(224,162,60,.14); color: var(--kc-gold-text); border: 1px solid rgba(224,162,60,.4); }
/* kaycie's mood bubbles on every notice (Zina 2026-07-15: "use more of the emotive speech
   bubbles to guide the flows") — sage check = all done, clay ! = something's off, amber
   bell = heads up, straight from the mascot spec. Pure CSS: every existing notice inherits. */
.kc-notice.kc-ok, .kc-notice.kc-err, .kc-notice.kc-warn { position: relative; padding-left: 3.15rem; }
.kc-notice.kc-ok::before, .kc-notice.kc-err::before, .kc-notice.kc-warn::before {
  content: ""; position: absolute; left: .85rem; top: .66rem; width: 27px; height: 26px;
  background-size: contain; background-repeat: no-repeat; }
.kc-notice.kc-ok::before   { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 62'%3E%3Cpath d='M14 6h37a11 11 0 0 1 11 11v19a11 11 0 0 1-11 11H29L16 59V47h-2A11 11 0 0 1 3 36V17A11 11 0 0 1 14 6Z' fill='%234E8C6A'/%3E%3Cpath d='M21 27.5l7.5 7.5 15-16' fill='none' stroke='%23FCF7F4' stroke-width='6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }
.kc-notice.kc-err::before  { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 62'%3E%3Cpath d='M14 6h37a11 11 0 0 1 11 11v19a11 11 0 0 1-11 11H29L16 59V47h-2A11 11 0 0 1 3 36V17A11 11 0 0 1 14 6Z' fill='%23CF6A4D'/%3E%3Cpath d='M32 15v13' stroke='%23FCF7F4' stroke-width='6' stroke-linecap='round'/%3E%3Ccircle cx='32' cy='37' r='3.5' fill='%23FCF7F4'/%3E%3C/svg%3E"); }
.kc-notice.kc-warn::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 62'%3E%3Cpath d='M14 6h37a11 11 0 0 1 11 11v19a11 11 0 0 1-11 11H29L16 59V47h-2A11 11 0 0 1 3 36V17A11 11 0 0 1 14 6Z' fill='%23E0A23C'/%3E%3Cpath d='M32 13a9 9 0 0 1 9 9c0 6 1.5 8 4 11H19c2.5-3 4-5 4-11a9 9 0 0 1 9-9Z' fill='%23FCF7F4'/%3E%3Ccircle cx='32' cy='36.5' r='3.4' fill='%23FCF7F4'/%3E%3C/svg%3E"); }

/* JetFormBuilder result messages inherit the SAME notice treatment (Zina 2026-07-18: Cara's
   quote submitted fine but nothing on screen said so — the JFB message was unstyled and
   hidden in a re-closed fold). The chrome JS reveals + scrolls to them; this makes them
   LOOK like every other kaycie notice, mascot bubble included. */
.kc-dash [class*="jet-form-builder-message"]            { padding: .72rem 1rem .72rem 3.15rem; border-radius: var(--kc-radius-btn);
                                                          margin: .6rem 0 1rem; font-size: .92rem; position: relative; }
.kc-dash [class*="jet-form-builder-message"]:empty      { display: none; }
.kc-dash [class*="jet-form-builder-message--success"]   { background: rgba(78,140,106,.12); color: #2f6b4d; border: 1px solid rgba(78,140,106,.3); }
.kc-dash [class*="jet-form-builder-message--error"]     { background: #f6e0e2; color: var(--kc-primary); border: 1px solid #efc9cd; }
.kc-dash [class*="jet-form-builder-message--success"]::before,
.kc-dash [class*="jet-form-builder-message--error"]::before {
  content: ""; position: absolute; left: .85rem; top: .66rem; width: 27px; height: 26px;
  background-size: contain; background-repeat: no-repeat; }
.kc-dash [class*="jet-form-builder-message--success"]::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 62'%3E%3Cpath d='M14 6h37a11 11 0 0 1 11 11v19a11 11 0 0 1-11 11H29L16 59V47h-2A11 11 0 0 1 3 36V17A11 11 0 0 1 14 6Z' fill='%234E8C6A'/%3E%3Cpath d='M21 27.5l7.5 7.5 15-16' fill='none' stroke='%23FCF7F4' stroke-width='6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }
.kc-dash [class*="jet-form-builder-message--error"]::before   { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 62'%3E%3Cpath d='M14 6h37a11 11 0 0 1 11 11v19a11 11 0 0 1-11 11H29L16 59V47h-2A11 11 0 0 1 3 36V17A11 11 0 0 1 14 6Z' fill='%23CF6A4D'/%3E%3Cpath d='M32 15v13' stroke='%23FCF7F4' stroke-width='6' stroke-linecap='round'/%3E%3Ccircle cx='32' cy='37' r='3.5' fill='%23FCF7F4'/%3E%3C/svg%3E"); }

/* the kaycie guide card — replaces the old How-to pill on every dashboard (Zina 2026-07-15);
   styled like the Home hero's dark mood panel, deep-links to the dashboard's guide section */
.kc-guide           { display: flex; align-items: center; gap: .75rem; max-width: 350px;
                      padding: .8rem 1rem !important; margin: 0; text-decoration: none;
                      transition: transform .15s ease, box-shadow .15s ease; }
.kc-guide:hover     { transform: translateY(-2px); box-shadow: var(--kc-shadow-deep); }
.kc-guide .kc-bubble{ flex: none; display: inline-flex; }
.kc-guide-tx        { display: flex; flex-direction: column; gap: .12rem; min-width: 0; }
.kc-guide .kc-eyebrow { color: var(--kc-gold); margin: 0; }
.kc-guide-t         { font-family: var(--kc-font-head); font-weight: 700; font-size: .95rem;
                      color: #FCF7F4; line-height: 1.35; }
.kc-guide-s         { font-size: .78rem; font-weight: 600; color: #c98f99; }
@media (max-width: 760px) { .kc-guide { max-width: 100%; margin-top: .6rem; } }
.kc-payfast-state   { list-style: none; padding: 0; margin: 0 0 1rem; color: var(--kc-muted); }
.kc-payfast-state li{ padding: .2rem 0; }

/* ---------- funder report / receipts ---------- */
.kc-funder-report h2 { margin-top: 0; font-family: var(--kc-font-head); color: var(--kc-ink); }
.kc-funder-summary  { display: flex; flex-wrap: wrap; gap: 1.5rem; list-style: none; padding: 0; margin: 0 0 1.5rem; }
.kc-funder-summary li { font-size: 1rem; color: var(--kc-muted); }
.kc-funder-summary strong { display: block; font-family: var(--kc-font-head); font-weight: 800; font-size: 1.9rem;
                      letter-spacing: -0.02em; color: var(--kc-ink); }
.kc-note            { color: var(--kc-muted); font-size: .85rem; }

/* ---------- dark ink hero panel (v9 utility — the design's feature card) ----------
   Wrap any block: <div class="kc-dark-card"> … </div>. Cream text, gold accents. */
.kc-dark-card       { background: linear-gradient(100deg, var(--kc-ink), var(--kc-primary-dk));
                      border-radius: var(--kc-radius-lg); padding: 1.5rem 1.6rem; color: #fcf7f4;
                      position: relative; overflow: hidden; box-shadow: 0 12px 34px -14px rgba(45,2,19,.55); margin: 0 0 1.15rem; }
.kc-dark-card::before { content: ""; position: absolute; right: -28px; top: -28px; width: 150px; height: 150px;
                      background: radial-gradient(circle, rgba(224,162,60,.22), transparent 70%); pointer-events: none; }
.kc-dark-card h2, .kc-dark-card h3 { font-family: var(--kc-font-head); font-weight: 800; color: #fcf7f4; margin: 0 0 .4rem; }
.kc-dark-card p     { color: #e9c9cf; font-size: .92rem; line-height: 1.55; }
.kc-dark-card .kc-eyebrow { color: var(--kc-gold); }
.kc-dark-card .kc-btn { background: var(--kc-gold); color: var(--kc-ink); }
.kc-dark-card .kc-btn:hover { background: var(--kc-gold-dk); color: var(--kc-ink); }

/* small uppercase eyebrow line (v9 utility — dates, kickers) */
.kc-eyebrow         { font-family: var(--kc-font-head); font-weight: 700; font-size: .72rem;
                      letter-spacing: .12em; text-transform: uppercase; color: var(--kc-rose); }

/* ---------- "Powered by Kaycie" footnote (pages + auto-injected under each form) ---------- */
/* Org & 18A form (2026-07-16): two-column grid — ten stacked full-width fields made the
   Admin page's first panel a wall. Address, the 18A switch and the button span both. */
.kc-org-settings form              { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .15rem 1.2rem; align-items: end; }
.kc-org-settings form > p          { margin: .3rem 0; }
.kc-org-settings form > p:has(textarea),
.kc-org-settings form > p:has(input[type="checkbox"]),
.kc-org-settings form > p:has(button) { grid-column: 1 / -1; }
.kc-org-settings input[type="text"], .kc-org-settings textarea { width: 100%; box-sizing: border-box; }
@media (max-width: 640px) { .kc-org-settings form { grid-template-columns: 1fr; } }

/* [kc_message] page copy (2026-07-16): privacy / thank-you / EFT bodies — readable
   measure centred under the tenant strip, headings in the kaycie face. */
.kc-msg             { max-width: 920px; margin: 0 auto; font-size: 1.02rem; line-height: 1.65; color: var(--kc-ink); }
.kc-msg h2          { font-family: var(--kc-font); font-weight: 800; letter-spacing: -.01em;
                      margin: 0 0 1.1rem; color: var(--kc-ink); }
.kc-msg p           { margin: 0 0 1.05rem; }
.kc-msg p:last-child{ margin-bottom: 0; }

/* public-page tenant chrome (2026-07-16): charity identity atop donor-facing pages */
.kc-pub-head        { display: flex; align-items: center; gap: .9rem; max-width: 920px;
                      margin: 0 auto 1.6rem; padding: .9rem 0 1.1rem; border-bottom: 1px solid var(--kc-line); }
.kc-pub-logo        { height: 46px; width: auto; border-radius: 8px; flex: none; }
.kc-pub-id          { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.kc-pub-id strong   { font-family: var(--kc-font); font-size: 1.05rem; color: var(--kc-ink); line-height: 1.2; }
.kc-pub-contact     { font-size: .8rem; color: var(--kc-muted-2); }
.kc-pub-site        { margin-left: auto; font-size: .85rem; font-weight: 700; color: var(--kc-primary);
                      text-decoration: none; white-space: nowrap; }
.kc-pub-site:hover  { text-decoration: underline; }
.kc-powered-text a  { font-size: .8rem; color: var(--kc-muted-2); text-decoration: none; opacity: .8; }
.kc-powered-text a:hover { opacity: 1; text-decoration: underline; }
@media (max-width: 560px) { .kc-pub-head { flex-wrap: wrap; } .kc-pub-site { margin-left: 0; flex-basis: 100%; } }

.kc-powered         { margin: 2rem auto .25rem; text-align: center; }
.kc-powered a       { display: inline-flex; align-items: center; gap: .5rem; font-size: .9rem;
                      color: var(--kc-muted); text-decoration: none; opacity: .8; transition: opacity .15s ease; }
.kc-powered a:hover { opacity: 1; }
.kc-powered img     { height: 300px; width: auto; vertical-align: middle; } /* Zina 2026-07-16: was 100px — rendered ~30% of intended (the logo asset carries wide padding) */

/* ---------- mobile ---------- */
@media (max-width: 560px) {
  .kc-dash          { padding: 1.25rem .85rem 1.5rem; }
  .kc-dash h1       { font-size: 1.55rem; }
  .kc-dash .kc-sub  { font-size: .95rem; }
  .kc-card          { padding: 1.1rem 1.05rem; }
  .kc-grid          { gap: .85rem; }
  .kc-stat .kc-num  { font-size: 1.55rem; }
  /* 16px inputs stop iOS Safari from zooming the page when a field is focused */
  .jet-form-builder input, .jet-form-builder select, .jet-form-builder textarea,
  .kc-payfast-settings input { font-size: 16px; }
  /* v9.3 (Zina 2026-07-11): buttons stop going full-width on phones — that rule made
     EVERY action (Mark read, row buttons, search) a giant bar. Only a form's own
     submit stays full-width; everything else keeps its natural size, one step smaller. */
  .jet-form-builder button[type=submit] { display: block; width: 100%; text-align: center; }
  .kc-btn { padding: .55rem 1rem; font-size: .86rem; }
  .kc-btn.kc-rowbtn { padding: .28rem .7rem; font-size: .76rem; }
}

/* ============================================================================
   Collapsible dashboard sections + per-page How-to link (v4, restyled v9).
   ============================================================================ */

/* page head row: title block left, how-to pill right */
.kc-head            { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; flex-wrap: wrap; }
/* v9: the gold-tinted pill from the design's header */
.kc-howto           { display: inline-flex; align-items: center; gap: .45rem; white-space: nowrap;
                      font-family: var(--kc-font); font-weight: 700; font-size: .84rem; color: var(--kc-ink);
                      background: rgba(224,162,60,.14); border: 1px solid rgba(224,162,60,.4); border-radius: 999px;
                      padding: .45rem .95rem; text-decoration: none; margin-top: .35rem;
                      transition: background .15s ease, border-color .15s ease; }
.kc-howto::before   { content: "?"; display: inline-grid; place-items: center; width: 1.15rem; height: 1.15rem;
                      border-radius: 50%; background: var(--kc-gold); color: var(--kc-ink); font-size: .78rem; font-weight: 800;
                      font-family: var(--kc-font-head); }
.kc-howto:hover     { background: rgba(224,162,60,.24); border-color: var(--kc-gold); color: var(--kc-ink); }

/* collapsible section = the design's white panel: bigger radius, gradient header
   band, a gold pulse-dot before the title */
details.kc-fold           { background: var(--kc-card); border: 1px solid var(--kc-line); border-radius: var(--kc-radius-lg);
                            box-shadow: var(--kc-shadow); margin: 0 0 1.15rem; overflow: hidden;
                            transition: box-shadow .16s ease; }
details.kc-fold[open]     { box-shadow: var(--kc-shadow-deep); }
details.kc-fold > summary { list-style: none; cursor: pointer; user-select: none;
                            padding: 1.05rem 1.4rem; font-family: var(--kc-font-head); font-weight: 800;
                            font-size: 1.08rem; letter-spacing: -0.015em; color: var(--kc-ink);
                            background: linear-gradient(90deg, #fff, var(--kc-bg-tint));
                            display: flex; align-items: center; gap: .7rem; }
details.kc-fold > summary::before { content: ""; width: 9px; height: 9px; border-radius: 50%; flex: none;
                                    background: var(--kc-gold); box-shadow: 0 0 0 4px rgba(224,162,60,.18); }
details.kc-fold > summary::-webkit-details-marker { display: none; }
details.kc-fold > summary::after { content: "\25BE"; color: var(--kc-muted-2); font-size: .95rem;
                                   margin-left: auto; transition: transform .18s ease; }
details.kc-fold[open] > summary::after { transform: rotate(180deg); }
details.kc-fold[open] > summary { border-bottom: 1px solid var(--kc-line-head); }
details.kc-fold > .kc-fold-body { padding: 1.2rem 1.4rem 1.35rem; }
details.kc-fold .kc-fold-note   { color: var(--kc-muted); font-size: .88rem; line-height: 1.55; margin: 0 0 1rem; }
/* summary count hint, e.g. <span class="kc-fold-hint">3 waiting</span> —
   v9: the wine count pill from the design's panel header */
.kc-fold-hint       { font-family: var(--kc-font-head); font-size: .74rem; font-weight: 700; color: #fcf7f4;
                      background: var(--kc-primary); border-radius: 999px; padding: .15rem .6rem; margin-left: auto; }
details.kc-fold > summary:has(.kc-fold-hint)::after { margin-left: .25rem; }

@media (max-width: 560px) {
  details.kc-fold > summary       { padding: .9rem 1.05rem; font-size: .99rem; }
  details.kc-fold > .kc-fold-body { padding: .95rem 1.05rem 1.1rem; }
  .kc-howto { margin-top: 0; }
}

/* v10 block-type fold variants (block framework):
   .kc-fold-sibling = a real second dataset that belongs here (Organisations, In-kind) —
   gold-tinted header + an "Also here" eyebrow, so it reads as a PEER, not the main event.
   .kc-fold-reference = system-generated proof you occasionally check (audit, notifications) —
   quiet grey, a "Read-only" pill, collapsed by default. */
details.kc-fold-sibling > summary         { background: linear-gradient(90deg, #fff, #f7edd8); }
details.kc-fold-sibling > summary::before { background: var(--kc-gold); }
.kc-fold-eyebrow    { font-family: var(--kc-font-head); font-weight: 800; font-size: .58rem; letter-spacing: .08em;
                      text-transform: uppercase; color: var(--kc-gold-text); background: #f2e2c4; padding: .12rem .5rem;
                      border-radius: 5px; margin-right: .1rem; }
details.kc-fold-reference           { background: #f7f1ee; border-color: var(--kc-line-mid); box-shadow: none; }
details.kc-fold-reference > summary { background: #f3ebe7; color: var(--kc-muted); font-weight: 700; }
details.kc-fold-reference > summary::before { background: var(--kc-muted-3); box-shadow: none; width: 7px; height: 7px; }
.kc-fold-ro         { font-family: var(--kc-font-head); font-weight: 800; font-size: .56rem; letter-spacing: .06em;
                      text-transform: uppercase; color: var(--kc-muted); background: #eaded8; padding: .13rem .5rem;
                      border-radius: 5px; margin-left: .5rem; }

/* block-framework STATE cards — standardised empty + blocked states */
.kc-state           { display: flex; align-items: center; gap: .9rem; border-radius: var(--kc-radius);
                      padding: 1.05rem 1.2rem; margin: .3rem 0 1rem; }
.kc-state-empty     { background: #fff; border: 1px solid var(--kc-line-mid); }
.kc-state-block     { background: #faedd2; border: 1px solid #ecd6a6; }
.kc-state-ic        { display: inline-flex; flex: none; width: 44px; height: 44px; border-radius: 12px;
                      align-items: center; justify-content: center; }
.kc-state-empty .kc-state-ic { background: var(--kc-bg); color: var(--kc-muted-2); }
.kc-state-block .kc-state-ic { background: #fff; color: #a56b12; }
.kc-state-t         { font-family: var(--kc-font-head); font-weight: 700; font-size: 1rem; color: var(--kc-ink); }
.kc-state-block .kc-state-t  { color: var(--kc-primary); }
.kc-state-s         { font-size: .86rem; color: var(--kc-muted); margin-top: .15rem; line-height: 1.5; }
/* the .kc-list empty state reuses .kc-state-empty but keeps a simple single line */
.kc-state-empty .kc-state-t  { font-weight: 700; color: var(--kc-muted); }

/* ============================================================================
   v11 — the BLOCK TAXONOMY (Stage 2). Every dashboard section declares its role
   through a class, so styling + future behaviour attach to the class, never to
   inline markup. Four block types (block framework) + form-reveal + settings.
     .kc-fold                default panel / MAIN LIST
     .kc-fold-sibling        a real 2nd dataset (gold header, "Also here")   [built]
     .kc-fold-reference      read-only proof (grey, "Read-only", collapsed)  [built]
     .kc-fold-quiet          a button reveals a FORM to do one thing         [built]
     .kc-tool                a TOOL — do, don't browse (icon · line · buttons; no accordion)
     .kc-settings-group      a heading that groups the Admin settings panels
   ============================================================================ */

/* TOOL block — framework type 3. NOT an accordion: a compact card, icon left,
   one line of copy, buttons right. Import / export / generate / bulk actions. */
.kc-tool            { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
                      background: var(--kc-card); border: 1px solid var(--kc-line-mid); border-radius: var(--kc-radius);
                      box-shadow: var(--kc-shadow); padding: 1.05rem 1.25rem; margin: 0 0 1.15rem; }
.kc-tool-ic         { width: 44px; height: 44px; border-radius: 12px; flex: none; display: inline-flex;
                      align-items: center; justify-content: center; background: var(--kc-soft); color: var(--kc-primary); }
.kc-tool-ic svg     { width: 22px; height: 22px; }
.kc-tool-main       { flex: 1; min-width: 190px; }
.kc-tool-title      { font-family: var(--kc-font-head); font-weight: 700; font-size: 1.02rem; color: var(--kc-ink); }
.kc-tool-note       { font-size: .85rem; color: var(--kc-muted); margin-top: .12rem; line-height: 1.45; }
.kc-tool-acts       { display: flex; gap: .55rem; flex: none; flex-wrap: wrap; align-items: center; }
/* a tool that needs a form: the button is a <details>; while CLOSED it sits inline in the
   tool's flex row; OPEN takes the full row so the form drops below full-width. (Deliberately
   not display:contents — that has known details/summary rendering + a11y hazards.) */
.kc-tool > details.kc-team-edit { flex: none; }
.kc-tool > details.kc-team-edit[open] { flex-basis: 100%; }
.kc-tool details.kc-team-edit > summary { list-style: none; }
.kc-tool details.kc-team-edit > summary::-webkit-details-marker { display: none; }
.kc-tool-form       { flex-basis: 100%; margin-top: .4rem; padding-top: .9rem; border-top: 1px solid var(--kc-line); }
@media (max-width: 560px){
  .kc-tool          { padding: .95rem 1.05rem; }
  .kc-tool-acts     { width: 100%; }
  .kc-tool-acts .kc-btn { flex: 1; text-align: center; }
}

/* SETTINGS GROUP heading — Admin's 15 panels grouped under labelled bands */
.kc-settings-group  { display: flex; align-items: center; gap: .7rem; margin: 2rem 0 .9rem; font-family: var(--kc-font-head);
                      font-size: .82rem; font-weight: 800; text-transform: uppercase; letter-spacing: .1em; color: var(--kc-muted); }
.kc-settings-group::before { content: ""; width: 26px; height: 2px; background: var(--kc-primary); border-radius: 2px; flex: none; }
.kc-settings-group::after  { content: ""; flex: 1; height: 1px; background: var(--kc-line); }
.kc-settings-group:first-of-type { margin-top: .5rem; }

/* THE NAV BAND: back link, how-to, next — three rows of cross-page navigation read as one
   group, closed by a single rule, then a real gap before the page's own identity begins. */
.kc-backhome        { margin-bottom: .55rem; }
.kc-journeys        { margin-bottom: .5rem; }
.kc-dash > .kc-next:last-of-type,
.kc-dash > .kc-next { padding-bottom: .9rem; border-bottom: 1px solid var(--kc-line); margin-bottom: 1.7rem; }
.kc-dash:not(:has(> .kc-next)) > .kc-journeys { padding-bottom: .9rem; border-bottom: 1px solid var(--kc-line); margin-bottom: 1.7rem; }

/* =====================================================================================
   FOCUS MODE (2026-08-18, Zina liked this instead of modal pop-ups). An open editor is
   already a distinct centred card, but the whole dashboard sits behind it competing for
   attention — which is the real reason a modal felt tempting. Dimming the rest buys the
   focus of a modal and keeps everything a modal would have cost: the URL still names what
   is open, the back button still works, post-redirect-get still guards the refresh, and
   there is no focus trap to get wrong.

   Nothing is BLOCKED. Dimmed content stays clickable, and hovering or tabbing into it
   brings it straight back — a dim that traps you is worse than no dim at all. The app bar
   sits outside .kc-dash and is never touched, so the way out is always lit.

   Needs :has(), which kaycie already depends on elsewhere. Where it is unsupported nothing
   dims and the page simply behaves as it did before.
   ===================================================================================== */
.kc-dash:has(#kc-editor) > *:not(#kc-editor):not(.kc-backhome) {
  opacity: .32; transition: opacity .18s ease;
}
.kc-dash:has(#kc-editor) > *:not(#kc-editor):not(.kc-backhome):hover,
.kc-dash:has(#kc-editor) > *:not(#kc-editor):not(.kc-backhome):focus-within {
  opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
  .kc-dash:has(#kc-editor) > *:not(#kc-editor):not(.kc-backhome) { transition: none; }
}

/* =====================================================================================
   SECTION HIERARCHY (2026-08-18, Zina: "I hate the same width, same colour, same styling
   treatment everywhere, it is visually so boring that people can't find what they want
   because there is no differentiation").

   The meaning was already in the markup and had been for a month — .kc-fold is the work,
   .kc-fold-sibling is "also here", .kc-fold-reference is "read-only proof". What was
   missing is that all three were the SAME OBJECT: a full-width white stripe with the same
   border, the same radius and the same summary bar. Three roles, one appearance, so the eye
   has nothing to sort by and every dashboard reads as one long undifferentiated column.

   The strongest signal available is not colour, it is WIDTH. A thing that is narrower than
   the thing above it is obviously subordinate to it, before you have read a word. So:

     PRIMARY    full width, white, a brand rule down its edge, the heaviest summary
     SIBLING    inset, tinted, lighter summary  — "there is more here, but it is not the job"
     REFERENCE  inset further, no card at all   — "proof you occasionally check"

   Colour and weight then reinforce what width has already said, rather than carrying it.
   ===================================================================================== */

/* PRIMARY — the work of this dashboard. The brand rule marks ONE section per page: the
   lead. An accent that repeats is not an accent, it is a pattern, and it stops pointing at
   anything. Every other primary fold keeps the heavier summary but not the rule. */
details.kc-fold-lead { border-left: 3px solid var(--kc-primary); }
details.kc-fold:not(.kc-fold-sibling):not(.kc-fold-reference):not(.kc-fold-quiet) > summary {
  font-size: 1.02rem; font-weight: 800;
}

/* SIBLING — a real second dataset, subordinate to the primary one */
details.kc-fold-sibling {
  width: calc(100% - 2.5rem); margin-left: auto; margin-right: auto;
  border-color: var(--kc-line-mid); box-shadow: none;
}
details.kc-fold-sibling > summary { font-size: .94rem; font-weight: 700; }

/* REFERENCE — system-generated proof; present, findable, and clearly not the job */
details.kc-fold-reference {
  width: calc(100% - 5rem); margin-left: auto; margin-right: auto;
  background: none; border: 0; border-top: 1px solid var(--kc-line);
  border-radius: 0; box-shadow: none;
}
details.kc-fold-reference > summary          { background: none; font-size: .88rem; font-weight: 700; color: var(--kc-muted); padding-left: 0; }
details.kc-fold-reference > summary::before  { background: var(--kc-muted-3); }
details.kc-fold-reference > .kc-fold-body    { padding-left: 0; padding-right: 0; }

/* On a phone the insets would just eat the screen — everything returns to full width and
   the tint, weight and rule do the sorting instead. */
@media (max-width: 700px) {
  details.kc-fold-sibling,
  details.kc-fold-reference { width: 100%; }
  details.kc-fold-reference { border-top-width: 2px; }
}

/* .kc-import — an import always sits DIRECTLY below (or above) the table it feeds
   (Zina 2026-07-13). A ghost-button summary; the file form drops open in place. */
.kc-import          { margin: 1rem 0 0; }
.kc-import > summary { list-style: none; display: inline-flex; align-items: center; gap: .4rem; cursor: pointer;
                      width: fit-content; }
.kc-import > summary::-webkit-details-marker { display: none; }
.kc-import > summary::before { content: ""; width: 15px; height: 15px; flex: none;
                      background: currentColor; -webkit-mask: var(--kc-import-ic) center/contain no-repeat; mask: var(--kc-import-ic) center/contain no-repeat; }
.kc-import          { --kc-import-ic: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v12m0 0l-4-4m4 4l4-4"/><path d="M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2"/></svg>'); }
/* the column contract, shown inline so nobody has to download anything to learn it
   (2026-08-18). Required headers carry the brand colour and a star. */
.kc-import-body code      { display: inline-block; background: var(--kc-bg); border: 1px solid var(--kc-line);
                            border-radius: 6px; padding: .1rem .4rem; margin: .12rem .18rem .12rem 0;
                            font-size: .78rem; color: var(--kc-muted); }
.kc-import-body code.kc-req { color: var(--kc-primary); border-color: var(--kc-line-mid); font-weight: 700; }
.kc-import-body .kc-form  { margin-bottom: 0; }

.kc-import-body     { margin-top: .9rem; padding-top: .95rem; border-top: 1px solid var(--kc-line); }
.kc-import-body .kc-fold-note { margin-top: 0; }

/* .kc-up — the branded upload control (Zina 2026-07-14). kaycie-uploads.js wraps every
   <input type=file> into this drop-zone: drag-and-drop + preview for images, client-side
   size/type validation with an inline error. Degrades to the native input if JS is off. */
.kc-up              { display: block; position: relative; border: 1.5px dashed var(--kc-line-mid, #e7d6d0);
                      border-radius: 12px; background: #fff; padding: .9rem 1rem; cursor: pointer; margin: .15rem 0;
                      transition: border-color .15s ease, background .15s ease; }
.kc-up:hover, .kc-up.kc-up-drag { border-color: var(--kc-primary); background: var(--kc-bg-tint, #fbf5f3); }
.kc-up-native       { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; }
.kc-up-face         { display: flex; align-items: center; gap: .6rem; color: var(--kc-muted);
                      font-size: .9rem; font-weight: 600; pointer-events: none; }
.kc-up-face.has     { color: var(--kc-ink); }
.kc-up-face .kc-up-tx b { color: var(--kc-primary); font-weight: 700; }
.kc-up-ic           { width: 22px; height: 22px; flex: none; background: currentColor;
                      -webkit-mask: var(--kc-up-icon) center/contain no-repeat; mask: var(--kc-up-icon) center/contain no-repeat; }
.kc-up              { --kc-up-icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M12 15V4m0 0l-4 4m4-4l4 4"/><path d="M4 15v3a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-3"/></svg>'); }
.kc-up-preview img  { display: block; max-height: 130px; max-width: 100%; margin-top: .65rem; border-radius: 8px; border: 1px solid var(--kc-line); }
.kc-up-err          { display: block; margin-top: .45rem; color: var(--kc-primary); font-size: .82rem; font-weight: 700; }
.kc-up-err:empty    { display: none; }

/* .kc-check — the STANDARD checkbox row (replaces per-form inline styles that
   overflowed on mobile). Input never shrinks; the label text wraps freely. */
.kc-check           { display: flex; align-items: flex-start; gap: .55rem; margin: .5rem 0;
                      font-size: .92rem; line-height: 1.45; color: var(--kc-ink); cursor: pointer; }
.kc-check > input[type=checkbox] { flex: none; width: 18px; height: 18px; margin: .12rem 0 0; accent-color: var(--kc-primary); }
.kc-check > span    { flex: 1; min-width: 0; }

/* ============================================================================
   Flow section headers + notification rows (v5, restyled v9).
   .kc-sec-head = the design's eyebrow: small caps Hanken 800, tinted icon chip
   in the flow colour, hairline rule filling the rest of the row.
   ============================================================================ */
.kc-sec-head        { display: flex; align-items: center; gap: .7rem; font-family: var(--kc-font-head);
                      font-size: .82rem; font-weight: 800; color: var(--kc-muted);
                      text-transform: uppercase; letter-spacing: .1em; margin: 2rem 0 1rem; }
.kc-sec-head::after { content: ""; flex: 1; height: 1px; background: var(--kc-line); }
/* the icon span (inline flow colour) becomes a tinted rounded chip */
.kc-sec-head > span:first-child { width: 30px; height: 30px; border-radius: 9px; align-items: center; justify-content: center;
                      background: color-mix(in srgb, currentColor 13%, transparent); flex: none; }
.kc-sec-head svg    { filter: none; }
.kc-notif           { border-radius: 10px; border-left: 3px solid transparent; }
.kc-notif:hover     { background: var(--kc-bg-tint); border-left-color: var(--kc-gold); }
.kc-notif svg       { margin-top: .1rem; }
/* phones: action buttons wrap under the message instead of squeezing it (375px insurance) */
@media (max-width: 560px) { .kc-notif { flex-wrap: wrap; } }

/* ============================================================================
   The "Next" pill row (v6, tokens refreshed v9).
   ============================================================================ */
/* Hoisted into the nav band (2026-08-18). The old top rule and negative margin belonged to
   its previous home BELOW the title; inside the band they cut it in two. The band closes
   with a single rule underneath the whole group instead. */
.kc-next            { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
                      margin: 0 0 .5rem; }
.kc-next-label      { font-family: var(--kc-font-head); font-size: .68rem; text-transform: uppercase; letter-spacing: .1em;
                      color: var(--kc-muted-2); font-weight: 800; }
.kc-next a          { display: inline-flex; align-items: center; gap: 6px; font-size: .8rem;
                      font-weight: 700; background: #fff; border: 1px solid var(--kc-line-mid);
                      border-radius: 999px; padding: .34rem .8rem; text-decoration: none;
                      transition: border-color .15s ease, background .15s ease; }
.kc-next a:hover    { border-color: currentColor; background: var(--kc-soft); }
.kc-next .kc-dot    { width: 8px; height: 8px; border-radius: 50%; flex: none; }

/* ============================================================================
   ID pickers + mobile polish (v7, tokens refreshed v9).
   ============================================================================ */
.kc-pickform        { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; margin: 0 0 1.1rem; }
.kc-pickform input, .kc-pickform select, .kc-pickform textarea {
                      padding: .62rem .85rem; border: 1px solid var(--kc-line); border-radius: var(--kc-radius-btn);
                      font-size: .95rem; font-family: var(--kc-font); color: var(--kc-ink); background: #fff; }
.kc-pickform input:focus, .kc-pickform select:focus, .kc-pickform textarea:focus { outline: none; border-color: var(--kc-primary); box-shadow: 0 0 0 3px rgba(var(--kc-primary-rgb),.12); }
.kc-pickform label  { font-weight: 700; font-size: .9rem; color: var(--kc-ink); }
select.kc-picked    { width: 100%; }

@media (max-width: 560px) {
  .kc-next          { gap: .4rem; }
  .kc-next a        { padding: .28rem .6rem; font-size: .76rem; }
  .kc-powered img   { height: 190px; }
  .kc-pickform      { flex-direction: column; align-items: stretch; }
  .kc-pickform input, .kc-pickform select, .kc-pickform .kc-btn { width: 100%; max-width: none !important; }
}

/* ============================================================================
   Type-ahead search + [kc_list] search + progress-update cards (v8, refreshed v9).
   ============================================================================ */
.kc-pick-search     { display: block; width: 100%; margin: 0 0 .45rem; padding: .55rem .85rem;
                      border: 1px solid var(--kc-line); border-radius: var(--kc-radius-btn); font-size: .95rem;
                      font-family: var(--kc-font); color: var(--kc-ink); background: #fff; box-sizing: border-box; }
.kc-pick-search:focus { outline: none; border-color: var(--kc-primary); box-shadow: 0 0 0 3px rgba(var(--kc-primary-rgb),.12); }
@media (max-width: 560px) { .kc-pick-search { font-size: 16px; } }

.kc-listsearch          { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; margin: 0 0 .8rem; }
.kc-listsearch input[type=search] { flex: 1; min-width: 180px; padding: .55rem .85rem; border: 1px solid var(--kc-line);
                          border-radius: var(--kc-radius-btn); font-size: .93rem; font-family: var(--kc-font); color: var(--kc-ink); background: #fff; }
.kc-listsearch input[type=search]:focus { outline: none; border-color: var(--kc-primary); box-shadow: 0 0 0 3px rgba(var(--kc-primary-rgb),.12); }
.kc-listsearch .kc-btn  { padding: .5rem 1.1rem; font-size: .86rem; }
.kc-listsearch-clear    { font-size: .85rem; color: var(--kc-muted); }
.kc-progress-form label { display: block; font-weight: 700; font-size: .9rem; margin-bottom: .35rem; color: var(--kc-ink); }
.kc-progress-form input[type=text], .kc-progress-form input[type=number], .kc-progress-form textarea, .kc-progress-form select {
                          width: 100%; padding: .65rem .85rem; border: 1px solid var(--kc-line); border-radius: var(--kc-radius-btn);
                          font-size: .95rem; font-family: var(--kc-font); color: var(--kc-ink); background: #fff; box-sizing: border-box; }
.kc-update              { background: var(--kc-card); border: 1px solid var(--kc-line); border-radius: var(--kc-radius);
                          box-shadow: var(--kc-shadow); padding: 1.2rem 1.35rem; margin: 0 0 1rem; }
.kc-update h3           { margin: 0 0 .25rem; font-family: var(--kc-font-head); font-weight: 700; font-size: 1.05rem; color: var(--kc-ink); }
.kc-update-meta         { color: var(--kc-muted-2); font-size: .82rem; margin: 0 0 .7rem; }
.kc-update-body         { font-size: .95rem; line-height: 1.6; color: var(--kc-ink); }
.kc-update-photo        { display: block; max-width: 100%; height: auto; border-radius: 10px; margin: 0 0 .8rem; }
@media (max-width: 560px) { .kc-listsearch input[type=search] { font-size: 16px; } }

/* ============================================================================
   [kc_team] panel (Core 0.5.37) — tokens refreshed v9.
   ============================================================================ */
.kc-team-add > summary { list-style: none; display: inline-block; cursor: pointer; margin: 0 0 1rem; }
.kc-team-add > summary::-webkit-details-marker { display: none; }
.kc-team-form           { background: var(--kc-bg); border: 1px solid var(--kc-line); border-radius: 12px;
                          padding: 1rem 1.1rem; margin: 0 0 1.2rem; }
.kc-team-namerow        { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 180px), 1fr));
                          gap: .6rem; margin-bottom: .8rem; }
.kc-team-namerow input  { padding: .6rem .85rem; border: 1px solid var(--kc-line); border-radius: var(--kc-radius-btn);
                          font-size: .95rem; font-family: var(--kc-font); box-sizing: border-box; }
.kc-team-invitebox      { display: block; font-size: .9rem; color: var(--kc-ink); margin: 0 0 .9rem; }
.kc-team-grid           { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr));
                          gap: .5rem .9rem; margin: 0 0 1rem; }
/* Access pickers as DROPDOWNS (Zina 2026-07-27): the tick-grids collapse behind a summary
   with a live "N of M ticked" count — the long horizontal list overwhelmed mobile. */
.kc-team-accfold           { margin: 0 0 .6rem; }
.kc-team-accfold > summary { list-style: none; display: inline-flex; align-items: center; gap: .4rem; cursor: pointer; }
.kc-team-accfold > summary::-webkit-details-marker { display: none; }
.kc-team-accfold[open] > summary { margin-bottom: .6rem; }
.kc-team-accfold .kc-team-section { margin: 0 0 .4rem; }
.kc-accfold-count          { font-weight: 800; }
/* Page-level access editor (2026-07-17): full-width card; role checkboxes with their
   deviation notes get room and rhythm. */
.kc-team-editor         { margin: .6rem 0 1.2rem; border-left: 5px solid var(--kc-primary); }
.kc-team-editor .kc-team-roles { grid-template-columns: repeat(auto-fill, minmax(min(100%, 270px), 1fr)); align-items: start; }
/* the two decisions on the access form (Zina 2026-07-20): screens they work on, then the
   powers they hold. Same checkboxes as before — grouped so authority never reads as "just
   another screen". The authority block is tinted so it's visibly the consequential half. */
.kc-team-section        { margin: .9rem 0 0; }
.kc-team-sechead        { font-family: var(--kc-font-head); font-weight: 700; font-size: .7rem;
                          letter-spacing: .09em; text-transform: uppercase; color: var(--kc-muted-2);
                          padding-bottom: .35rem; margin-bottom: .55rem; border-bottom: 1px solid var(--kc-line); }
.kc-team-section--auth  { background: var(--kc-bg-tint); border: 1px solid var(--kc-line);
                          border-radius: 12px; padding: .8rem .9rem; }
.kc-team-section--auth .kc-team-sechead { color: var(--kc-primary); border-bottom-color: var(--kc-line-mid); }
.kc-team-role           { display: block; font-size: .88rem; font-weight: 700; color: var(--kc-ink); line-height: 1.35; }
.kc-team-role input     { accent-color: var(--kc-primary); margin-right: .3rem; }
.kc-team-role .kc-note, .kc-team-role small { font-weight: 400; color: var(--kc-muted); }
.kc-team-mod            { display: flex; align-items: center; justify-content: space-between; gap: .5rem;
                          font-size: .87rem; color: var(--kc-ink); }
.kc-team-mod select     { padding: .35rem .5rem; border: 1px solid var(--kc-line); border-radius: 8px;
                          font-size: .85rem; font-family: var(--kc-font); }
.kc-team-actions        { white-space: nowrap; }
.kc-team-actions .kc-btn { padding: .3rem .8rem; font-size: .8rem; margin: 0 .25rem .25rem 0; }
.kc-team-edit           { display: inline-block; }
.kc-team-edit > summary { list-style: none; cursor: pointer; }
.kc-team-edit > summary::-webkit-details-marker { display: none; }
.kc-team-edit[open] > form { position: relative; z-index: 5; background: #fff; border: 1px solid var(--kc-line);
                          border-radius: 12px; box-shadow: var(--kc-shadow-lift); padding: 1rem;
                          margin-top: .4rem; min-width: min(420px, 80vw); white-space: normal; }
@media (max-width: 560px) { .kc-team-actions { white-space: normal; } }

/* =====================================================================================
   COLUMN WIDTHS BY DATA TYPE (2026-08-18, Zina: "status can be wider. Do we need to do a
   pass to make sure our column widths are appropriate?").

   Yes — but table by table would be forty hand-tuned guesses that drift apart. The table
   primitive ALREADY knows what each column is: it stamps `kc-col-id` / `kc-col-chip` on the
   header and `kc-chipcell` / `kc-moneycell` on the cell. Those hooks simply carried no width
   rules, so every column negotiated its own width from its content and the longest one won —
   which is why a three-digit quantity could hold as much room as a name.

   Sized by TYPE, once, here. Every table inherits it and none of them need touching:

     identity  the flexible one — takes whatever is left, because names are what you read
     chip      wide enough for the longest status word, and NEVER wrapping ("Partly funded"
               broken across two lines is unreadable and makes the row taller than its
               neighbours)
     money     enough for a formatted amount, no more
     actions   already 1% + nowrap, unchanged
   ===================================================================================== */
.kc-list th.kc-col-chip,
.kc-list td.kc-chipcell   { white-space: nowrap; width: 1%; min-width: 8.5rem; }
.kc-list td.kc-moneycell  { white-space: nowrap; width: 1%; min-width: 7rem; }
.kc-list th.kc-col-id     { width: auto; }

/* On a phone the cards layout takes over and these widths stop applying — a nowrap chip in
   a stacked card would push the card sideways. */
@media (max-width: 700px) {
  .kc-list th.kc-col-chip,
  .kc-list td.kc-chipcell,
  .kc-list td.kc-moneycell { width: auto; min-width: 0; white-space: normal; }
}

/* row-action buttons inside [kc_list actions="..."] */
.kc-row-actions         { white-space: nowrap; }
/* Action column now LEADS every table (Zina 2026-07-12) — keep it tight so the data still
   reads first-glance, and let the header cell shrink to its buttons. */
.kc-list th.kc-col-actions,
.kc-list td.kc-row-actions { width: 1%; white-space: nowrap; }
.kc-btn.kc-rowbtn       { padding: .28rem .7rem; font-size: .78rem; margin: 0 .2rem .2rem 0; border-radius: 9px;
                          white-space: nowrap; /* the cell wraps BETWEEN buttons, never inside a label */ }
@media (max-width: 560px) { .kc-row-actions { white-space: normal; } }

/* v9.3 — icon row-actions (Zina 2026-07-11: "show the icons in each table, with a key").
   A quiet 34px ghost square: wine glyph, wine fill on hover. The words live in the
   tooltip/aria-label and in the .kc-key line under the table. */
.kc-iconbtn             { display: inline-flex; align-items: center; justify-content: center;
                          width: 34px; height: 34px; padding: 0; box-sizing: border-box; vertical-align: middle;
                          background: transparent; color: var(--kc-primary); border: 1px solid var(--kc-line-mid);
                          border-radius: 9px; cursor: pointer; text-decoration: none; margin: 0 .2rem .2rem 0;
                          transition: background .15s ease, color .15s ease, border-color .15s ease; }
.kc-iconbtn:hover       { background: var(--kc-primary); color: #fcf7f4; border-color: var(--kc-primary); }
.kc-iconbtn svg         { display: block; }
/* the key: which icon means what, once, under the table */
.kc-key                 { display: flex; flex-wrap: wrap; gap: .35rem 1.1rem; align-items: center;
                          margin: .55rem 0 0; font-size: .76rem; color: var(--kc-muted); }
.kc-key-item            { display: inline-flex; align-items: center; gap: .35rem; white-space: nowrap; }
.kc-key-item svg        { color: var(--kc-primary); flex: none; }

/* ============================================================================
   v10 — the LIST PATTERN (Zina 2026-07-12, "a list, not a table"). Actions collapse
   into ONE ⋯ dropdown that TRAILS each row — so the table is narrow enough to drop
   the horizontal slider. On phones each row folds into a labelled card. Status/flag
   columns render as chips ("signal, not raw cells"). Same --kc-* tokens.
   ============================================================================ */
/* chips beyond the three status tones */
.kc-badge-neutral       { background: var(--kc-soft); color: var(--kc-muted); }
.kc-badge-flag          { background: rgba(var(--kc-primary-rgb),.10); color: var(--kc-primary); }
.kc-cellmuted           { color: var(--kc-muted-3); }

/* The three-way match, shown on the pay form: quote vs goods received vs invoice.
   Green when they agree, amber when something needs a human eye (2026-07-21). */
.kc-match           { border: 1px solid var(--kc-line); border-radius: 10px; padding: .55rem .7rem; margin: .5rem 0 .7rem;
                      background: var(--kc-bg-tint); font-size: .82rem; }
.kc-match--ok       { border-color: #b9d8c4; background: #f2f9f4; }
.kc-match--check    { border-color: var(--kc-gold); background: #fdf6e7; }
.kc-match-t         { font-family: var(--kc-font-head); font-weight: 700; font-size: .74rem; letter-spacing: .06em;
                      text-transform: uppercase; color: var(--kc-muted-2); margin-bottom: .35rem; }
.kc-match-r         { display: flex; justify-content: space-between; gap: 1rem; padding: .12rem 0; }
.kc-match-r span    { color: var(--kc-muted); }
.kc-match-bad       { color: var(--kc-primary); }

/* A panel that IS the task right now — the 18A request form opened from a row button.
   It used to render above a long table, so the click looked like it did nothing (Zina
   2026-07-20). Now it is unmistakably the subject, and flashes once on arrival. */
.kc-s18a--focus     { border: 2px solid var(--kc-primary); box-shadow: var(--kc-shadow-lift); scroll-margin-top: 84px; }
.kc-flash           { animation: kc-flash 2.1s ease-out 1; }
@keyframes kc-flash {
  0%   { box-shadow: 0 0 0 0 rgba(var(--kc-primary-rgb),.45); }
  35%  { box-shadow: 0 0 0 10px rgba(var(--kc-primary-rgb),0); }
  100% { box-shadow: var(--kc-shadow-lift); }
}
@media (prefers-reduced-motion: reduce) { .kc-flash { animation: none; } }

/* [kc_share_links] — the one box of public links (Admin & setup, 2026-07-20) */
.kc-sharerow        { padding: .75rem 0; border-top: 1px solid var(--kc-line); }
.kc-sharerow:first-child { border-top: 0; padding-top: 0; }
.kc-sharerow-t      { font-family: var(--kc-font-head); font-weight: 700; font-size: .96rem; color: var(--kc-ink); }
.kc-sharerow-in     { display: flex; gap: .5rem; align-items: center; margin-top: .5rem; flex-wrap: wrap; }
.kc-sharerow-in input { flex: 1 1 16rem; min-width: 0; max-width: 30rem; font-size: .85rem; }
@media (max-width: 560px) {
  .kc-sharerow-in input { flex: 1 1 100%; }
}

/* identity cell — avatar + name (used on the desktop table AND the mobile card) */
/* the row name as a link to the record (2026-08-18). Underline only on hover/focus: a
   whole column of underlines reads as noise, but it must never be a mystery-click either,
   so the colour is the ink and the affordance appears the moment you point at it. */
.kc-idlink          { color: inherit; text-decoration: none; border-bottom: 1px solid transparent; }
.kc-idlink:hover,
.kc-idlink:focus-visible { color: var(--kc-primary); border-bottom-color: currentColor; }
.kc-idlink:focus-visible { outline: 2px solid var(--kc-primary); outline-offset: 2px; border-radius: 3px; }

.kc-idcell .kc-idwrap   { display: inline-flex; align-items: center; gap: .6rem; min-width: 0; }
.kc-av                  { width: 34px; height: 34px; border-radius: 50%; flex: none; display: inline-flex;
                          align-items: center; justify-content: center; background: var(--kc-soft); color: var(--kc-primary);
                          font-family: var(--kc-font-head); font-weight: 700; font-size: .78rem; letter-spacing: .01em; }
.kc-idname              { font-weight: 800; overflow: hidden; text-overflow: ellipsis; }

/* the ⋯ actions dropdown — the SAME control on desktop and mobile */
.kc-kebab               { position: relative; display: inline-flex; }
.kc-kebab-btn           { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px;
                          padding: 0; border: 1px solid var(--kc-line-mid); border-radius: 9px; background: #fff;
                          color: var(--kc-muted); font-size: 1.2rem; line-height: 1; cursor: pointer;
                          transition: border-color .15s ease, color .15s ease; }
.kc-kebab-btn:hover, .kc-kebab.open .kc-kebab-btn { border-color: var(--kc-primary); color: var(--kc-primary); }
.kc-kebab-body          { display: none; position: absolute; top: calc(100% + 6px); right: 0; z-index: 40;
                          min-width: 186px; max-width: min(340px, calc(100vw - 1.7rem)); flex-direction: column;
                          align-items: stretch; background: #fff;
                          border: 1px solid var(--kc-line); border-radius: 12px; box-shadow: var(--kc-shadow-lift); padding: .4rem; }
/* an OPEN ⋯ menu must never be clipped by the table's scroll container (Zina 2026-07-15:
   the resolutions signature form was cut off) — release the overflow while a menu is open */
.kc-list-wrap:has(.kc-kebab.open),
.kc-list-wrap:has(details.kc-team-edit[open]) { overflow: visible; }
/* #26 (2026-07-18): the FOLD is the real clipping ancestor — release it while any row menu
   or inline editor is open. .kc-kebab--up is set by the chrome JS when there's no viewport
   room below: the menu opens UPWARD instead of clipping off the bottom of the screen. */
details.kc-fold:has(.kc-kebab.open),
details.kc-fold:has(details.kc-team-edit[open]) { overflow: visible; }
.kc-kebab.kc-kebab--up .kc-kebab-body { top: auto; bottom: calc(100% + 6px); }
.kc-kebab.open .kc-kebab-body { display: flex; }
.kc-kebab-body form     { display: block; margin: 0; }
/* bespoke actions that need a form (Spending sign-off, record-paid) live inside the SAME ⋯
   dropdown as everything else: the popover summary reads as a menu item; its form drops
   open below, within a slightly wider menu. */
.kc-kebab-body--wide    { min-width: 244px; max-width: min(320px, calc(100vw - 1.7rem)); }
.kc-kebab-body details.kc-team-edit          { width: 100%; }
.kc-kebab-body details.kc-team-edit > summary::-webkit-details-marker { display: none; }
.kc-kebab-body details.kc-team-edit > summary { list-style: none; }
.kc-kebab-body details.kc-team-edit[open] > summary { background: var(--kc-bg-tint); color: var(--kc-primary); }
.kc-kebab-body details.kc-team-edit > form   { padding: .2rem .55rem .45rem; }
.kc-kebab-body details.kc-team-edit p        { margin: .4rem 0; }
.kc-kebab-body details.kc-team-edit .kc-note { font-size: .78rem; line-height: 1.45; }
.kc-kebab-body details.kc-team-edit input[type=text],
.kc-kebab-body details.kc-team-edit textarea,
.kc-kebab-body details.kc-team-edit input[type=file] { width: 100%; box-sizing: border-box; font-size: 16px; }
.kc-kebab-body > .kc-note { display: block; padding: .35rem .6rem; font-size: .8rem; color: var(--kc-muted); }
/* one menu row: icon + words, full width */
.kc-menuitem            { display: flex; align-items: center; gap: .55rem; width: 100%; box-sizing: border-box;
                          padding: .5rem .6rem; border: 0; border-radius: 9px; background: none; cursor: pointer;
                          font-family: var(--kc-font); font-weight: 700; font-size: .87rem; color: var(--kc-ink);
                          text-align: left; text-decoration: none; white-space: nowrap; }
.kc-menuitem:hover      { background: var(--kc-bg-tint); }
.kc-menuitem-ic         { display: inline-flex; width: 16px; flex: none; color: var(--kc-primary); }
.kc-menuitem-ic svg     { display: block; }
.kc-dash a.kc-menuitem       { color: var(--kc-ink); }
.kc-dash a.kc-menuitem:hover { color: var(--kc-primary); }
/* a menu row that only STATES something (already signed, "yours") — not a control */
.kc-menuitem--static          { cursor: default; color: var(--kc-muted); font-weight: 700; }
.kc-menuitem--static:hover    { background: none; }
.kc-menuitem--static .kc-menuitem-ic { color: var(--kc-muted); }
/* Theme button styles must never repaint the ⋯ button (Zina 2026-07-20: it went dark
   charcoal while a menu was open — the theme's button:active/:focus won on specificity).
   Pin every state explicitly, at higher specificity than any `button:state` rule. */
.kc-kebab .kc-kebab-btn,
.kc-kebab .kc-kebab-btn:focus,
.kc-kebab .kc-kebab-btn:active { background: #fff; color: var(--kc-muted); border-color: var(--kc-line-mid); }
.kc-kebab .kc-kebab-btn:hover,
.kc-kebab .kc-kebab-btn:focus-visible,
.kc-kebab .kc-kebab-btn:active,
.kc-kebab.open .kc-kebab-btn   { background: var(--kc-bg-tint); border-color: var(--kc-primary); color: var(--kc-primary); }
/* the same protection for menu rows rendered as <button> */
.kc-kebab-body .kc-menuitem,
.kc-kebab-body .kc-menuitem:focus,
.kc-kebab-body .kc-menuitem:active { background: none; color: var(--kc-ink); }
.kc-kebab-body .kc-menuitem:hover,
.kc-kebab-body .kc-menuitem:active { background: var(--kc-bg-tint); color: var(--kc-ink); }
/* comfortable thumb targets on touch screens (Zina 2026-07-20: mobile clickability):
   44px minimum for the ⋯ button and every row inside an open menu. */
@media (pointer: coarse) {
  .kc-kebab-btn        { width: 42px; height: 42px; }
  .kc-menuitem         { min-height: 44px; padding-top: .65rem; padding-bottom: .65rem; }
  .kc-appmenu-item     { min-height: 44px; }
  .kc-appmenu-pin      { min-height: 44px; }
}

/* actions column trails the row, tight + right-aligned; no slider needed anymore.
   Scoped to --cards so module tables (plain .kc-list) keep their own action layout. */
.kc-list--cards th.kc-col-actions, .kc-list--cards td.kc-row-actions { width: 1%; white-space: nowrap; text-align: right; }
.kc-list-wrap                        { overflow-x: auto; }              /* module tables still scroll if wide */
.kc-list-wrap:has(.kc-list--cards)   { overflow: visible; }            /* card tables: the ⋯ menu must not clip */

/* action_mode="buttons" — the visible-button action column (Giving/Sales: the action IS the job) */
.kc-list--cards td.kc-row-actions--btn { white-space: normal; }
.kc-list--cards td.kc-row-actions--btn .kc-rowbtn { margin: 0 0 .2rem .3rem; }
.kc-btn-danger, .kc-btn-danger:hover { background: #fff; border: 1.5px solid var(--kc-line-mid); color: var(--kc-primary); }

/* status tabs ([kc_list tab_col="…"] + a .kc-tabs bar; filtered client-side by the chrome JS) */
.kc-tabs            { display: flex; flex-wrap: wrap; gap: .4rem; margin: 0 0 .95rem; }
.kc-tabs button, .kc-tabs a { font-family: var(--kc-font-head); font-weight: 800; font-size: .78rem; cursor: pointer;
                      background: #fff; border: 1px solid var(--kc-line-mid); color: var(--kc-muted);
                      border-radius: 999px; padding: .34rem .9rem; text-decoration: none; transition: border-color .12s, color .12s, background .12s; }
.kc-tabs button:hover, .kc-tabs a:hover { border-color: var(--kc-primary); color: var(--kc-primary); }
.kc-tabs .is-on     { background: var(--kc-primary); border-color: var(--kc-primary); color: #fcf7f4; }
.kc-dash .kc-tabs a        { color: var(--kc-muted); }        /* neutralise the generic wine link colour */
.kc-dash .kc-tabs a.is-on  { color: #fcf7f4; }

/* The identity-card transform applies ONLY to [kc_list] output (.kc-list--cards). Plain
   .kc-list tables from the module plugins keep the normal table (scroll on mobile) until
   they're migrated — the transform must never blank an untagged table. */
@media (max-width: 640px) {
  .kc-list--cards, .kc-list--cards tbody, .kc-list--cards tr { display: block; }
  .kc-list--cards thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .kc-list--cards tr    { position: relative; background: var(--kc-card); border: 1px solid var(--kc-line);
                          border-radius: 14px; box-shadow: var(--kc-shadow); margin: 0 0 .6rem; padding: .7rem 3.2rem .7rem .85rem; }
  .kc-list--cards tbody tr:hover td { background: none; }
  /* the identity LIST: only the name + status/flag chips show; email/phone/dates stay on the
     desktop table. Tap the ⋯ to act, or the row opens the record. */
  .kc-list--cards tbody td     { display: none; padding: 0; border: none; }
  .kc-list--cards td::before   { display: none; }
  .kc-list--cards td.kc-idcell { display: block; }
  .kc-list--cards .kc-idname   { font-size: 1.04rem; }
  .kc-list--cards td.kc-chipcell { display: inline-flex; margin: .45rem .35rem 0 0; }
  .kc-list--cards td.kc-chipcell:has(.kc-cellmuted) { display: none; }  /* off-flags stay hidden on mobile */
  /* money stays visible on phones (amount is the point of a giving/sales row) */
  .kc-list--cards td.kc-moneycell { display: inline-flex; align-items: center; margin: .45rem .55rem 0 0;
                             font-family: var(--kc-font-head); font-weight: 800; color: var(--kc-ink); }
  /* the ⋯ pins top-right of the card */
  .kc-list--cards td.kc-row-actions { display: block; position: absolute; top: .6rem; right: .6rem; padding: 0; width: auto; }
  /* button-mode actions flow ON the card (below name+amount), never pinned like the ⋯ */
  .kc-list--cards td.kc-row-actions--btn { position: static; margin: .5rem 0 0; padding: 0 .85rem; text-align: left; }
  .kc-list--cards td.kc-row-actions--btn .kc-rowbtn { margin: 0 .3rem .2rem 0; }

  /* MODULE tables (plain .kc-list — quotes, resolutions, cashbook, invoices, audit, boards…)
     fold into LABELLED cards: every field keeps its header. No identity-hiding — these aren't
     people lists. data-label is injected by the chrome script from each table's <th>. */
  .kc-list:not(.kc-list--cards)            { display: block; }
  .kc-list:not(.kc-list--cards) thead      { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .kc-list:not(.kc-list--cards) tbody      { display: block; }
  .kc-list:not(.kc-list--cards) tr         { display: block; position: relative; background: var(--kc-card);
                                             border: 1px solid var(--kc-line); border-radius: 14px; box-shadow: var(--kc-shadow);
                                             margin: 0 0 .6rem; padding: .3rem .25rem; }
  .kc-list:not(.kc-list--cards) tbody tr:hover td { background: none; }
  .kc-list:not(.kc-list--cards) td         { display: flex; align-items: flex-start; justify-content: space-between;
                                             gap: 1rem; border: none; padding: .42rem .85rem; text-align: right; }
  .kc-list:not(.kc-list--cards) td::before { content: attr(data-label); flex: none; text-align: left;
                                             font-family: var(--kc-font-head); font-weight: 800; font-size: .64rem;
                                             text-transform: uppercase; letter-spacing: .05em; color: var(--kc-muted-2); }
  .kc-list:not(.kc-list--cards) td:empty   { display: none; }
  /* action-heavy cells (Team edit-access, Spending sign-off) stack full-width so their forms /
     buttons never get crammed into a right-aligned column */
  .kc-list:not(.kc-list--cards) td:has(form),
  .kc-list:not(.kc-list--cards) td:has(details),
  .kc-list:not(.kc-list--cards) td:has(.kc-btn) { display: block; text-align: left; }
  .kc-list:not(.kc-list--cards) td:has(form)::before,
  .kc-list:not(.kc-list--cards) td:has(details)::before,
  .kc-list:not(.kc-list--cards) td:has(.kc-btn)::before { display: block; margin-bottom: .3rem; }
}

/* mobile: the custom (non-JFB) inputs need the same 16px iOS anti-zoom treatment,
   and the team edit-access popover must never overflow small screens */
@media (max-width: 560px) {
  .kc-team-namerow input, .kc-team-mod select, .kc-progress-form input,
  .kc-progress-form textarea, .kc-progress-form select, .kc-pickform input,
  .kc-pickform select { font-size: 16px; }
  .kc-team-edit           { display: block; }
  .kc-team-edit[open] > form { min-width: 0; width: 100%; box-sizing: border-box; }
}

/* ============================================================================
   [kc_notify_bar] — global unread banner (Core 0.5.39), refreshed v9.
   ============================================================================ */
.kc-notifybar           { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap;
                          background: #fff; border: 1px solid var(--kc-line);
                          border-radius: 12px; padding: .6rem 1rem; margin: 0 0 1.15rem;
                          text-decoration: none; color: var(--kc-ink); font-size: .88rem;
                          font-weight: 700; box-shadow: var(--kc-shadow);
                          transition: border-color .15s ease, box-shadow .15s ease; }
.kc-notifybar:hover     { border-color: var(--kc-gold); box-shadow: var(--kc-shadow-lift); background: #fff; }
.kc-notifybar-cat       { display: inline-flex; align-items: center; gap: .3rem; }
.kc-notifybar-cat b     { font-family: var(--kc-font-head); font-size: .85rem; }
.kc-notifybar-text      { color: var(--kc-muted); font-weight: 700; }

/* boards admin add-item form (boards 0.2.7) — breathing room + mobile */
.kc-b-form input[type=text]   { width: 100%; max-width: 420px; }
.kc-b-form input, .kc-b-form select, .kc-b-form textarea {
                                padding: .5rem .7rem; border: 1px solid var(--kc-line); border-radius: var(--kc-radius-btn);
                                font-family: var(--kc-font); font-size: .93rem; }
.kc-b-form p                  { margin: .6rem 0; }
@media (max-width: 560px) { .kc-b-form input, .kc-b-form select { font-size: 16px; } }
/* iOS anti-zoom, GLOBAL (Zina 2026-07-27 supplier-page sweep): any text-entry control inside a
   card zooms the page on focus if its font is under 16px. The per-form rules above cover the
   known forms; this catches every other card form — supplier portal, editors, future tools. */
@media (max-width: 560px) {
  .kc-card input[type=text], .kc-card input[type=email], .kc-card input[type=number],
  .kc-card input[type=tel], .kc-card input[type=date], .kc-card input[type=url],
  .kc-card textarea, .kc-card select { font-size: 16px; }
}

/* ============================================================================
   v9.1 — the structural pass (Core 0.5.67): hero, KPI deltas, launcher chips.
   ============================================================================ */

/* [kc_home_hero] — welcome left, the dark kaycie state panel right */
.kc-hero            { display: grid; grid-template-columns: 1.55fr 1fr; gap: 1.4rem; align-items: stretch; margin: 0 0 1.5rem; }
.kc-hero-left       { display: flex; flex-direction: column; justify-content: center; align-items: flex-start; gap: .15rem; }
.kc-hero-left .kc-sub { margin-bottom: .9rem; }
.kc-hero-mood       { margin: 0; display: flex; flex-direction: column; justify-content: center; }
.kc-hero-mood h3    { font-size: 1.2rem; margin: .35rem 0 .3rem; }
.kc-hero-mood p     { margin: 0; font-size: .88rem; }
@media (max-width: 760px) { .kc-hero { grid-template-columns: 1fr; } }

/* KPI delta line under a stat number ([kc_sum delta="1"] / the sign-off tile) */
.kc-statline        { display: block; font-family: var(--kc-font); font-size: .74rem; font-weight: 700; margin-top: .3rem; letter-spacing: 0; }
.kc-statline-up     { color: var(--kc-green); }
.kc-statline-down   { color: var(--kc-primary); }
.kc-statline-hot    { color: var(--kc-gold-text); }
.kc-card.kc-stat-hot { border-left: 3px solid var(--kc-gold); }

/* launcher card top row: tinted icon chip left, live stat right */
.kc-card-top        { display: flex; align-items: flex-start; justify-content: space-between; gap: .6rem; margin: 0 0 .8rem; }
.kc-chip            { width: 38px; height: 38px; border-radius: 10px; display: inline-flex; align-items: center; justify-content: center;
                      background: color-mix(in srgb, currentColor 12%, transparent); flex: none; }
.kc-cardstat        { text-align: right; line-height: 1.05; }
.kc-cardstat b      { display: block; font-family: var(--kc-font-head); font-weight: 800; font-size: 1.3rem; letter-spacing: -0.02em; color: var(--kc-ink); }
.kc-cardstat small  { font-size: .67rem; color: var(--kc-muted-2); }
.kc-cardstat-hot b, .kc-cardstat-hot small { color: var(--kc-gold-text); }
.kc-launcher > .kc-card { min-height: 172px; }

/* v10 home — the HUB card (Programmes) reads as the centre: wine ring + soft lift. */
.kc-card-hub        { border: 1.5px solid var(--kc-primary); box-shadow: 0 10px 26px -14px rgba(var(--kc-primary-rgb),.4); }
.kc-card-hub > h3   { color: var(--kc-primary); }
.kc-hub-badge       { display: inline-block; font-family: var(--kc-font-head); font-weight: 800; font-size: .6rem;
                      letter-spacing: .07em; text-transform: uppercase; color: var(--kc-primary);
                      background: var(--kc-soft); padding: .18rem .5rem; border-radius: 6px; margin: 0 0 .7rem; }
/* v10 home — the attention line under a launcher card (only when a real query backs it) */
.kc-cardalert       { display: inline-block; font-family: var(--kc-font-head); font-weight: 800; font-size: .74rem;
                      padding: .28rem .6rem; border-radius: 8px; margin: 0 0 .8rem; }
.kc-cardalert-warn  { background: rgba(224,162,60,.16); color: var(--kc-gold-text); }
.kc-cardalert-ok    { background: rgba(78,140,106,.16); color: #2f6b4d; }
.kc-cardalert-care  { background: var(--kc-soft); color: var(--kc-primary); }

/* v10 home — the "Needs you" wine strip ([kc_needs_you]): the top waiting items, each a
   deep-link named by its verb. Stays quiet when nothing waits. Current palette. */
.kc-needs           { background: var(--kc-primary); color: #fff; border-radius: var(--kc-radius);
                      padding: .95rem 1.1rem .7rem; margin: 0 0 1.5rem; box-shadow: var(--kc-shadow-deep); }
.kc-needs-hd        { display: flex; align-items: center; gap: .5rem; font-family: var(--kc-font-head);
                      font-weight: 800; font-size: 1rem; letter-spacing: -.01em; margin: 0 0 .35rem; }
.kc-needs-count     { margin-left: auto; background: rgba(255,255,255,.18); border-radius: 999px;
                      font-family: var(--kc-font); font-weight: 800; font-size: .74rem; padding: .12rem .6rem; }
.kc-needs-item      { display: flex; align-items: center; gap: .7rem; padding: .6rem 0;
                      border-top: 1px solid rgba(255,255,255,.14); text-decoration: none; font-weight: 700; font-size: .9rem; }
.kc-needs-ic        { display: inline-flex; flex: none; opacity: .92; }
.kc-needs-ic svg    { display: block; }
.kc-needs-tx        { flex: 1; min-width: 0; }
.kc-needs-go        { margin-left: auto; flex: none; font-family: var(--kc-font-head); font-weight: 800; font-size: .82rem; white-space: nowrap; }
.kc-needs-more      { display: inline-block; margin: .55rem 0 .1rem; font-family: var(--kc-font-head); font-weight: 800; font-size: .8rem; text-decoration: none; }
/* the strip lives inside .kc-dash, whose generic link colour is wine — force white/gold here */
.kc-dash .kc-needs a, .kc-dash .kc-needs a:hover        { color: #fff; }
.kc-dash .kc-needs-go, .kc-dash .kc-needs-more,
.kc-needs-item:hover .kc-needs-go                       { color: var(--kc-gold-pale); }
.kc-needs-item:hover .kc-needs-tx                       { text-decoration: underline; }

/* keep dark-card CTAs on one line so the trailing → never wraps (design fix, v9.2) */
.kc-dark-card .kc-btn, .kc-setup-side .kc-btn { white-space: nowrap; }

/* the dark Admin & setup feature panel with the setup-% side block */
.kc-setup-card      { display: flex; align-items: center; gap: 1.5rem; margin-bottom: 1.6rem; }
.kc-setup-main      { flex: 1; }
.kc-setup-main p    { max-width: 560px; }
.kc-setup-side      { text-align: right; flex: none; }
.kc-setup-pct       { font-family: var(--kc-font-head); font-weight: 800; font-size: 1.7rem; color: var(--kc-gold-pale); }
.kc-setup-lbl       { font-size: .68rem; letter-spacing: .06em; text-transform: uppercase; color: var(--kc-rose); margin: 0 0 .7rem; }
@media (max-width: 640px) { .kc-setup-card { flex-direction: column; align-items: flex-start; } .kc-setup-side { text-align: left; } }

/* ============================================================================
   v9.2 — the dashboard CHROME (design's kaycie-chrome.css, merged into the one
   file). App bar + slim footer, rendered by Core's KC_Chrome on /account pages
   (wp_body_open / wp_footer). Same --kc-* tokens throughout.
   ============================================================================ */

/* ---------- app bar ---------- */
.kc-appbar          { position: sticky; top: 0; z-index: 30;
                      background: rgba(252,247,244,.85); backdrop-filter: blur(10px);
                      -webkit-backdrop-filter: blur(10px); border-bottom: 1px solid var(--kc-line);
                      font-family: var(--kc-font); }
.kc-appbar-in       { max-width: 1140px; margin: 0 auto; padding: 0 1rem; height: 64px;
                      display: flex; align-items: center; gap: 1.1rem; }

/* brand lockup (bubble svg + wordmark) */
.kc-brand           { display: flex; align-items: center; gap: .55rem; text-decoration: none; flex: none; }
.kc-brand-name      { font-family: var(--kc-font-head); font-weight: 800; font-size: 1.35rem;
                      letter-spacing: -0.03em; color: var(--kc-ink); }
.kc-bubble          { display: block; flex: none; }          /* wraps an inline mascot SVG */

.kc-appbar-div      { width: 1px; height: 26px; background: var(--kc-line-mid); flex: none; }

/* org name (single-tenant: a label, not a switcher) */
.kc-org             { display: flex; align-items: center; gap: .5rem; background: none; border: 0; cursor: default;
                      padding: .4rem .5rem; border-radius: 8px; font-family: var(--kc-font);
                      font-weight: 700; font-size: .9rem; color: var(--kc-ink); }
.kc-org svg         { color: var(--kc-muted-2); }

.kc-appbar-spacer   { flex: 1; }

/* header search retired v9.4 (Zina: "not useful") — replaced by the dashboards Menu.
   Styles kept one version for un-updated markup, then delete. */
.kc-appsearch       { display: flex; align-items: center; gap: .5rem; background: #fff;
                      border: 1px solid var(--kc-line); border-radius: 10px; padding: .5rem .75rem;
                      width: 230px; transition: border-color .12s ease, box-shadow .12s ease; }
.kc-appsearch svg   { color: var(--kc-muted-3); flex: none; }
.kc-appsearch input { border: 0; outline: 0; background: none; width: 100%; font-family: var(--kc-font);
                      font-size: .87rem; color: var(--kc-ink); }

/* v9.4 — the dashboards Menu (a details-dropdown; JS in the chrome closes it on outside click) */
.kc-appmenu           { position: relative; }
.kc-appmenu > summary { list-style: none; display: inline-flex; align-items: center; gap: .45rem;
                        cursor: pointer; font-family: var(--kc-font); font-weight: 700; font-size: .84rem;
                        color: var(--kc-ink); background: #fff; border: 1px solid var(--kc-line);
                        border-radius: 10px; padding: .5rem .85rem; user-select: none;
                        transition: border-color .12s ease, box-shadow .12s ease; }
.kc-appmenu > summary::-webkit-details-marker { display: none; }
.kc-appmenu > summary:hover, .kc-appmenu[open] > summary { border-color: var(--kc-primary); box-shadow: 0 0 0 3px rgba(var(--kc-primary-rgb),.12); }
/* v10 — the grouped dashboards menu (Zina 2026-07-12): work-flow sections, pinned
   Needs-you, per-item subtitles. Same --kc-* tokens; no palette change. */
.kc-appmenu-list      { position: absolute; top: calc(100% + 8px); right: 0; z-index: 60;
                        width: 320px; max-width: calc(100vw - 1.7rem); max-height: 76vh; max-height: 76dvh;
                        overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
                        background: #fff; border: 1px solid var(--kc-line); border-radius: 16px;
                        box-shadow: var(--kc-shadow-lift); padding: .5rem .45rem .6rem; }
/* pinned Needs-you row */
.kc-appmenu-pin       { display: flex; align-items: center; gap: .6rem; text-decoration: none;
                        background: var(--kc-primary); color: #fcf7f4; border-radius: 12px;
                        padding: .6rem .7rem; margin: .1rem .2rem .3rem; }
.kc-appmenu-pin:hover { background: var(--kc-primary-dk); color: #fcf7f4; }
.kc-appmenu-pin-ic    { display: flex; flex: none; }
.kc-appmenu-pin-ic svg{ width: 18px; height: 18px; }
.kc-appmenu-pin-tx    { font-family: var(--kc-font-head); font-weight: 700; font-size: .95rem; line-height: 1.15; }
.kc-appmenu-pin-sub   { display: block; font-family: var(--kc-font); font-weight: 700; font-size: .69rem; color: #e7c6ce; margin-top: 1px; }
.kc-appmenu-pin-badge { margin-left: auto; background: var(--kc-gold); color: #4a2d05; font-family: var(--kc-font-head);
                        font-weight: 700; font-size: .74rem; padding: .1rem .55rem; border-radius: 999px; flex: none; }
/* group */
.kc-appmenu-group     { padding: .25rem 0 .1rem; }
.kc-appmenu-glabel    { display: flex; align-items: center; gap: .5rem; padding: .4rem .55rem .35rem; }
.kc-appmenu-gic       { width: 22px; height: 22px; border-radius: 7px; background: var(--kc-soft); color: var(--kc-primary);
                        display: flex; align-items: center; justify-content: center; flex: none; }
.kc-appmenu-gic svg   { width: 13px; height: 13px; }
.kc-appmenu-gt        { font-family: var(--kc-font-head); font-weight: 700; font-size: .64rem; letter-spacing: .1em;
                        text-transform: uppercase; color: var(--kc-muted-2); }
.kc-appmenu-gr        { flex: 1; height: 1px; background: var(--kc-line); }
/* item */
.kc-appmenu-item      { display: flex; align-items: center; gap: .5rem; text-decoration: none; color: var(--kc-ink);
                        padding: .5rem .6rem; border-radius: 9px; }
.kc-appmenu-item:hover{ background: var(--kc-bg-tint); }
.kc-appmenu-imain     { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.kc-appmenu-it        { font-family: var(--kc-font); font-weight: 700; font-size: .9rem; line-height: 1.2; }
.kc-appmenu-item:hover .kc-appmenu-it { color: var(--kc-primary); }
.kc-appmenu-isub      { font-family: var(--kc-font); font-weight: 600; font-size: .72rem; color: var(--kc-muted-2);
                        margin-top: 1px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kc-appmenu-arrow     { flex: none; font-weight: 800; color: var(--kc-muted-3); transition: color .12s ease, transform .12s ease; }
.kc-appmenu-item:hover .kc-appmenu-arrow { color: var(--kc-primary); transform: translateX(2px); }
/* sign out: last item, set off by a rule (switch-user affordance) */
.kc-appmenu-signout   { border-top: 1px solid var(--kc-line); border-radius: 0 0 9px 9px; margin-top: .45rem; padding-top: .6rem; }

/* user cluster: mood bubble + avatar */
.kc-appuser         { display: flex; align-items: center; gap: .55rem; flex: none; }
.kc-avatar          { width: 34px; height: 34px; border-radius: 50%; background: var(--kc-primary);
                      color: #fcf7f4; display: flex; align-items: center; justify-content: center;
                      font-family: var(--kc-font-head); font-weight: 700; font-size: .82rem; flex: none;
                      text-decoration: none; }

/* the header reuses .kc-howto (already in this file) for the guide pill */

/* ---------- slim dashboard footer ---------- */
.kc-appfoot         { background: var(--kc-ink); color: var(--kc-rose); font-family: var(--kc-font); }
.kc-appfoot-in      { max-width: 1140px; margin: 0 auto; padding: 1.35rem 1rem;
                      display: flex; align-items: center; gap: .65rem; font-size: .8rem; flex-wrap: wrap; }
.kc-appfoot .kc-brand-name { color: #fcf7f4; font-size: 1.05rem; }
.kc-appfoot-tag     { color: var(--kc-rose); }
.kc-appfoot-spacer  { flex: 1; }
.kc-appfoot a       { color: var(--kc-gold-pale); text-decoration: none; }
.kc-appfoot a:hover { color: #fcf7f4; }

@media (max-width: 760px) {
  .kc-appbar-in     { gap: .7rem; padding: 0 .85rem; }
  .kc-appsearch     { display: none; }
  .kc-org           { display: none; }
  /* the Menu STAYS on phones (it's most useful there); the how-to pill steps back */
  .kc-appbar .kc-howto { display: none; }
  .kc-appmenu > summary { padding: .45rem .7rem; }
  /* v10 — on phones the dropdown right-anchors to the Menu button, which isn't at the
     screen edge, so a fixed-width panel overflowed the left. Make it a viewport-anchored
     sheet with equal side gutters (matches the mockup's near-full-width mobile menu). */
  .kc-appmenu-list  { position: fixed; top: 60px; left: .85rem; right: .85rem; width: auto;
                      max-width: none; max-height: calc(100vh - 74px); max-height: calc(100dvh - 74px);
                      padding-bottom: max(.6rem, env(safe-area-inset-bottom)); }
  /* Zina's own view: the WP admin bar (46px on mobile) pushed the fixed menu down, cutting the
     last group (Portals — where Supplier portal lives) off the bottom. Tenants never see the
     admin bar; this only corrects the admin's preview. */
  body.admin-bar .kc-appmenu-list { top: 106px; max-height: calc(100vh - 120px); max-height: calc(100dvh - 120px); }
}
@media (max-width: 560px) {
  .kc-appfoot-in    { flex-direction: column; align-items: flex-start; gap: .4rem; }
  .kc-appfoot-spacer{ display: none; }
}

/* When the kaycie chrome is on the page, the THEME's own header/footer retire.
   Scoped to body:has(.kc-appbar) so nothing changes anywhere else. Covers the
   common theme/builder wrappers; the belt-and-braces alternative remains setting
   the /account page to the theme's blank template. */
body:has(.kc-appbar) > header:not(.kc-appbar),
body:has(.kc-appbar) .site-header,
body:has(.kc-appbar) #masthead,
body:has(.kc-appbar) #site-header,
body:has(.kc-appbar) header.elementor-location-header,
body:has(.kc-appbar) .elementor-location-header,
body:has(.kc-appbar) footer.elementor-location-footer,
body:has(.kc-appbar) .elementor-location-footer,
body:has(.kc-appbar) .site-footer,
body:has(.kc-appbar) #colophon,
body:has(.kc-appbar) #site-footer,
/* kaycie.co.za's actual wrappers: JetThemeCore locations (verified on the live homepage) */
body:has(.kc-appbar) #jet-theme-core-header,
body:has(.kc-appbar) #jet-theme-core-footer,
body:has(.kc-appbar) .jet-theme-core-location--header-location,
body:has(.kc-appbar) .jet-theme-core-location--footer-location { display: none !important; }

/* ============================================================================
   v9 body baseline — the warmer canvas + Mulish everywhere the dashboards live.
   Scoped to pages that carry a dashboard so the marketing theme is untouched.
   ============================================================================ */
body:has(.kc-dash)      { background: var(--kc-bg); }
.kc-dash ::selection    { background: var(--kc-gold-pale); }
.kc-dash a              { color: var(--kc-primary); }
.kc-dash a:hover        { color: var(--kc-primary-dk); }
/* the generic link colour must not repaint these */
.kc-dash a.kc-howto, .kc-dash a.kc-howto:hover { color: var(--kc-ink); }
.kc-dash a.kc-btn:not(.kc-btn-ghost):not(.kc-btn-gold),
.kc-dash a.kc-btn:not(.kc-btn-ghost):not(.kc-btn-gold):hover,
.kc-dash a.kc-btn:not(.kc-btn-ghost):not(.kc-btn-gold):visited,
.kc-dash a.kc-btn:not(.kc-btn-ghost):not(.kc-btn-gold):focus,
.kc-dash a.kc-btn:not(.kc-btn-ghost):not(.kc-btn-gold):active { color: #fcf7f4; }
.kc-dash a.kc-btn-gold, .kc-dash a.kc-btn-gold:hover,
.kc-dash a.kc-btn-gold:visited, .kc-dash a.kc-btn-gold:focus, .kc-dash a.kc-btn-gold:active { color: var(--kc-ink); }
.kc-dash a.kc-btn-ghost:hover { color: #fcf7f4; }
/* v9.4 a11y (Zina: "hover has dark text on dark background"): the generic .kc-dash a:hover
   wine text was winning over icon buttons' hover fill — wine-on-wine. Cream glyph wins. */
.kc-dash a.kc-iconbtn:hover { color: #fcf7f4; }
/* plain links inside the ink hero/dark cards must never take the wine link colour */
.kc-dark-card a:not(.kc-btn), .kc-dark-card a:not(.kc-btn):hover { color: var(--kc-gold-pale); }

/* ---------- brand-colour pickers (Admin → Custom styling) ---------- */
.kc-brand-row  { display: flex; flex-wrap: wrap; gap: 1.25rem; margin: .6rem 0 1rem; }
.kc-brand-pick { display: flex; align-items: center; gap: .65rem; cursor: pointer; }
.kc-brand-pick input[type=color] { width: 52px; height: 38px; padding: 2px; border: 1px solid var(--kc-line-mid);
                                   border-radius: 10px; background: var(--kc-card); cursor: pointer; }
.kc-brand-pick b     { display: block; font-size: .9rem; }
.kc-brand-pick small { display: block; color: var(--kc-muted); font-size: .78rem; }
/* the two sample buttons under the pickers — display only, never clickable */
.kc-brand-prev { display: flex; flex-wrap: wrap; gap: .6rem; margin: 0 0 .35rem; pointer-events: none; }

/* ---------- Admin & setup card grid (#28, 2026-07-18 — "copy the home dashboard layout") ----
   [kc_admin_view] groups the page's .kc-tool cards into grids per settings-group and hides the
   folds; each card links to ?kca=<fold-id>, a focused full-width view of just that section. */
.kc-admin-cardgrid            { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
                                gap: .8rem; margin: 0 0 1.2rem; }
.kc-admin-cardgrid .kc-tool   { flex-direction: column; align-items: flex-start; gap: .55rem;
                                height: 100%; margin: 0; }
.kc-admin-cardgrid .kc-tool-main { min-width: 0; }
.kc-admin-cardgrid .kc-tool-note { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
                                overflow: hidden; }
.kc-admin-cardgrid .kc-tool-acts { margin-top: auto; }
.kc-admin-cardgrid .kc-tool   { cursor: pointer; transition: box-shadow .15s ease, transform .15s ease; }
.kc-admin-cardgrid .kc-tool:hover { box-shadow: var(--kc-shadow-deep); transform: translateY(-2px); }
.kc-tool-title .kc-badge      { margin-left: .45rem; vertical-align: middle; }
.kc-adminfocus                { display: flex; align-items: center; gap: .8rem; margin: 0 0 .9rem; }

/* Picker mirror (2026-07-19): the original JFB input stays in the form for the framework's
   own state/validation; the enhancer's <select> is the visible control. Kept 1px (not
   display:none) so any native validation bubble still has an anchor. */
.kc-pick-mirrored { position: absolute !important; width: 1px !important; height: 1px !important;
                    opacity: 0 !important; pointer-events: none !important; margin: 0 !important;
                    padding: 0 !important; border: 0 !important; }

/* Public board items on phones (Zina 2026-07-27): the 3-cell rows squashed the item name and
   the "monthly" badge, and crammed the pledge button. Stack the cells; the button goes full
   width. Appended AFTER the module-table card rules so it wins the tie on specificity. */
@media (max-width: 640px) {
  .kc-board .kc-list td             { display: block !important; text-align: left !important;
                                      white-space: normal !important; justify-content: flex-start; padding: .28rem .85rem; }
  .kc-board .kc-list td:first-child { padding-top: .6rem; }
  .kc-board .kc-list td:last-child  { padding-bottom: .65rem; }
  .kc-board .kc-list td .kc-btn     { display: block; text-align: center; margin-top: .2rem; }
  .kc-board .kc-list .kc-badge      { display: inline-block; margin-left: .3rem; }
}

/* Cofund amount callout (Zina 2026-07-27): "any amount" guidance was small grey text UNDER
   the field — donors missed it. Now a soft highlighted line above the amount box. */
.kc-amt-callout { background: var(--kc-soft); color: var(--kc-primary); font-weight: 600;
                  font-size: .92rem; line-height: 1.45; border-radius: 10px;
                  padding: .55rem .8rem; margin: 0 0 .6rem; }

/* TRUE inline row editing on the boards admin items table (Zina 2026-07-27 v2): each cell
   holds its display value + a hidden field; "Edit item" (row ⋯ menu) flips the row so the
   values BECOME fields in place, with the ticks + Save/Cancel surfacing on the action line. */
/* TABLE HEADER ROW (2026-08-18, Zina: the bulk-edit button "needs to be in our burgundy and
   it needs to be in the top right corner of the table for best ux"). The convention for any
   action that operates on a WHOLE table: title left, action right, above the table.

   Above rather than below because you decide to edit before you read, and right rather than
   left because the row actions are already on the right — a table-level action belongs in
   the same column as the row-level ones. On a phone it drops under the title full-width;
   a small button floated beside a wrapping heading is how you get a mis-tap.

   The button is the PRIMARY colour, not a ghost: it is the main thing you can do to this
   table, and a ghost button in a header reads as decoration. */
.kc-tablehead        { display: flex; align-items: center; justify-content: space-between;
                       gap: .75rem; flex-wrap: wrap; margin: 0 0 .35rem; }
.kc-tablehead > h3   { margin: 0; }
.kc-tablehead-acts   { display: flex; gap: .5rem; align-items: center; margin-left: auto; }
.kc-tablehead-acts .kc-btn { font-size: .84rem; padding: .42rem .95rem; }
@media (max-width: 620px) {
  .kc-tablehead      { align-items: stretch; }
  .kc-tablehead-acts { margin-left: 0; width: 100%; }
  .kc-tablehead-acts .kc-btn { width: 100%; text-align: center; justify-content: center; }
}

/* bulk-edit grid cells (2026-08-18): always visible, unlike the per-row inline editor.
   16px so a phone never zooms when you tab down a column. */
.kc-bulkin        { width: 100%; min-width: 4.5rem; box-sizing: border-box; font-size: 16px;
                    font-family: var(--kc-font); padding: .45rem .55rem;
                    border: 1px solid var(--kc-line); border-radius: 8px; background: #fff; color: var(--kc-ink); }
.kc-bulkin:focus  { outline: none; border-color: var(--kc-primary); box-shadow: 0 0 0 3px rgba(var(--kc-primary-rgb), .12); }
/* Short numeric cells (a quantity is rarely more than three digits) get their own width so
   the column stops stealing room from the names beside it. Matches the per-row inline
   editor, which has always used ~5rem for qty. */
.kc-bulkin--sm    { max-width: 5rem; min-width: 3.2rem; }

/* Bulk consent uploader review table (0.6.176) — file → match chip → person select. */
.kc-bulkc table            { width: 100%; border-collapse: collapse; font-size: .92rem; margin: .35rem 0 .9rem; }
.kc-bulkc th               { text-align: left; font-size: .78rem; text-transform: uppercase; letter-spacing: .04em;
                             color: var(--kc-muted); padding: .45rem .6rem; border-bottom: 1px solid var(--kc-line); }
.kc-bulkc td               { text-align: left; padding: .55rem .6rem; border-bottom: 1px solid var(--kc-line); vertical-align: middle; }
.kc-bulkc td select        { max-width: 100%; margin: 0; }
.kc-bulkc .kc-bulkc-file   { word-break: break-all; max-width: 16rem; }
@media (max-width: 640px) {           /* stack the three columns as one block per file */
  .kc-bulkc thead          { display: none; }
  .kc-bulkc tr             { display: block; padding: .45rem 0; border-bottom: 1px solid var(--kc-line); }
  .kc-bulkc td             { display: block; border: 0; padding: .18rem .1rem; }
  .kc-bulkc .kc-bulkc-file { max-width: none; font-weight: 600; }
}

.kc-ie-i, .kc-ie-save            { display: none; }
tr.kc-editing .kc-ie-v           { display: none; }
tr.kc-editing .kc-ie-i           { display: inline-block; width: 100%; min-width: 4.5rem; font-size: 16px; }
tr.kc-editing .kc-ie-save        { display: flex; flex-wrap: wrap; gap: .45rem .9rem; align-items: center; }
tr.kc-editing td                 { vertical-align: top; }
@media (max-width: 640px) {
  tr.kc-editing .kc-ie-i         { width: 100%; }
}

/* ── Mobile: ⋯ menus in the LABELLED-ROW table layout (Zina 2026-07-27) ──────────
   In card mode the kebab is pinned top-right so its right-anchored menu fits. In the
   module/labelled-row layout the actions cell sits mid-row, so a right-anchored menu
   opened ~100px off the LEFT edge — invisible. Give the cell its own full-width line
   and open the menu leftward-anchored instead. */
@media (max-width: 640px) {
  .kc-list:not(.kc-list--cards) td.kc-row-actions          { display: block; text-align: left; }
  .kc-list:not(.kc-list--cards) td.kc-row-actions::before  { display: block; margin-bottom: .3rem; }
  .kc-list:not(.kc-list--cards) .kc-kebab-body             { right: auto; left: 0; }
}

/* ── Public-page text hierarchy (Zina 2026-07-27) ───────────────────────────────
   Boards and the programme page are public LANDING pages, not dashboards: the huge
   dashboard h1 shouted while the two TRUST lines under it — which programme this
   supports, and a human to call — were whispered in muted .kc-note grey. Same rule
   everywhere: title sized for a landing page, trust lines read as CONTENT.
   Scale: h1 (identity) → .kc-sub (intro prose) → .kc-meta (trust) → .kc-note (aside). */
.kc-board h1, .kc-prog-public h1, .kc-board-report h2 {
                      font-size: clamp(1.5rem, 4.4vw, 1.95rem); line-height: 1.12; }
.kc-meta            { font-size: .95rem; color: var(--kc-ink); line-height: 1.5; margin: 0 0 .45rem; }
.kc-meta + .kc-meta { margin-top: -.1rem; }
.kc-meta a          { color: var(--kc-primary); font-weight: 700;
                      text-decoration: underline; text-underline-offset: 2px; }
.kc-meta .kc-meta-lbl { color: var(--kc-muted); }
@media (max-width: 560px) { .kc-meta { font-size: .92rem; } }

/* ---------- no-access page (2026-08-16) ----------
   A user without a dashboard's capability used to get a BLANK page — reached in practice
   via a notification deep-link after a role change, i.e. the system sent them somewhere
   and then showed them nothing. Reuses the state-card vocabulary; only the page-level
   centring is new. */
.kc-no-access        { max-width: 44rem; margin: 3rem auto; }
.kc-no-access .kc-state { align-items: flex-start; }
.kc-no-access p      { margin-top: 1.1rem; }
/* the variance note on the three-way match — wraps, since it is a sentence not a figure */
.kc-match-why           { align-items: flex-start; }
.kc-match-why strong    { font-weight: 600; text-align: right; max-width: 22rem; line-height: 1.45; }
/* small PDF link beside a consent chip (2026-08-16) — the register is where someone goes
   when a school or hospital asks for a copy, so the document hangs off the status. */
.kc-doclink        { font-size: .74rem; font-weight: 700; letter-spacing: .04em; margin-left: .35rem;
                     color: var(--kc-primary); text-decoration: none; border-bottom: 1px solid currentColor; }
.kc-doclink:hover  { color: var(--kc-primary-dk); }

/* ============================================================================
   v12 — FORM PRIMITIVE + UTILITIES (2026-08-16)

   Zina: "I def want all forms to look like our login." The login card was the only
   coherent form in the system because it is ONE block of CSS applied to ONE screen;
   dashboard forms had no primitive at all, so each re-declared its own layout inline.
   The audit counted 381 inline style= attributes, 22 of them the same flex string.

   Inline styles beat stylesheet rules, so this primitive only takes full effect as
   those are stripped (docs/STYLING-AUDIT.md §6). Adding it is safe on its own: it
   changes nothing that does not opt in via .kc-form.
   ========================================================================== */

/* --- utilities: what most of the 381 inline styles actually wanted --- */
.kc-num-col, .kc-ta-r { text-align: right; }
.kc-ta-c              { text-align: center; }
.kc-flush             { margin: 0; }
.kc-mt-1              { margin-top: .5rem; }
.kc-mt-2              { margin-top: 1rem; }
.kc-mt-3              { margin-top: 1.6rem; }
.kc-inline            { display: inline; }
.kc-row               { display: flex; gap: .5rem; align-items: center; }
.kc-row--baseline     { display: flex; gap: .5rem; align-items: baseline; }
.kc-row--wrap         { flex-wrap: wrap; }
.kc-w-xs              { max-width: 5rem; }
.kc-w-sm              { max-width: 7rem; }
.kc-w-md              { max-width: 10rem; }
.kc-w-lg              { max-width: 18rem; }

/* --- .kc-form: the login card, made reusable ---
   Same card, radius, shadow, input treatment and focus ring as KC_Login::skin(), so a
   dashboard form and the sign-in screen read as one system. */
.kc-form {
  /* radius and padding are the LOGIN CARD's own values (22px / clamp 28-40), not a
     near-miss — Zina: "that's the one I want to copy". */
  background: #fff; border: 1px solid var(--kc-line); border-radius: 22px;
  box-shadow: var(--kc-shadow-deep); padding: clamp(28px, 5vw, 40px); margin: 0 0 1.1rem;
  max-width: 34rem; display: flex; flex-direction: column; align-items: stretch; gap: 14px;
}
.kc-form--wide  { max-width: 46rem; }
.kc-form--flush { box-shadow: none; border-radius: 14px; padding: 18px 20px; }

/* MEASURED AGAINST THE LOGIN CARD, not remembered (2026-08-18). Zina asked four times why
   dashboard forms still did not look like the login form. They were close but never equal,
   and the gap was in four small values that add up: the login labels are in the DISPLAY
   face, its inputs are roomier, its border is the lighter line, and its labels carry a gap
   underneath. These are now the login card's own numbers, taken from site/pages/login.html
   by diffing the computed styles of both forms side by side. */
.kc-form label { display: block; font-family: var(--kc-font-head); font-weight: 600;
                 color: var(--kc-ink); font-size: 14px; margin: 0 0 6px; }
.kc-form input[type=text], .kc-form input[type=email], .kc-form input[type=tel],
.kc-form input[type=url],  .kc-form input[type=number], .kc-form input[type=date],
.kc-form input[type=password], .kc-form select, .kc-form textarea {
  width: 100%; margin-top: 0; background: #fff; color: var(--kc-ink);
  border: 1px solid var(--kc-line); border-radius: 10px; padding: 12px 14px;
  /* 16px: anything smaller makes iOS zoom the whole page on focus */
  font-size: 16px; font-family: var(--kc-font); box-sizing: border-box;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.kc-form textarea { min-height: 5.5rem; resize: vertical; }
.kc-form input:focus, .kc-form select:focus, .kc-form textarea:focus {
  outline: none; border-color: var(--kc-primary);
  box-shadow: 0 0 0 3px rgba(var(--kc-primary-rgb), .12);
}
.kc-form input[aria-invalid="true"], .kc-form .kc-field-bad input {
  border-color: var(--kc-primary); background: #fffafa;
}
/* a checkbox/radio row reads as one line, not a stacked label */
.kc-form .kc-check { display: flex; gap: .55rem; align-items: flex-start; font-weight: 400; }
.kc-form .kc-check input { flex: none; width: 18px; height: 18px; margin-top: .18rem; }
/* two fields side by side where they belong together (first/last, amount/date) */
.kc-form .kc-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.kc-form .kc-note { font-weight: 400; }
/* The action row is a ROW, not another paragraph (2026-08-18, Zina: "the save button is
   not obvious"). A rule above it separates deciding from filling in, and the primary
   action goes full-width on a phone where a small button is easy to miss entirely. */
.kc-form-actions   { display: flex; gap: .6rem; flex-wrap: wrap; align-items: center;
                     margin-top: .5rem; padding-top: .9rem; border-top: 1px solid var(--kc-line); }
.kc-form-actions .kc-btn { font-size: 16px; padding: 13px 20px; border-radius: 12px; }
@media (max-width: 560px) {
  .kc-form-actions { flex-direction: column; align-items: stretch; }
  .kc-form-actions .kc-btn { width: 100%; text-align: center; justify-content: center; }
}

@media (max-width: 620px) {
  .kc-form { padding: 18px 16px; border-radius: 14px; }
  .kc-form .kc-pair { grid-template-columns: 1fr; }
}

/* =====================================================================================
   A CARD INSIDE A CARD IS THE BUG (2026-08-18, Zina, with a screenshot of Contacts: "why
   does my contacts form still not look like yours? there is a styling element we keep
   missing").

   The form WAS on the login card — that part worked. The trouble is that .kc-form carries
   its own max-width (34rem, right for a sign-in screen standing alone) and its own card
   chrome. Drop that inside an editor panel, which is already a full-width .kc-card, and you
   get a 544px card floating in a 1150px one: a narrow column of fields and a great empty
   white area beside it. It reads as broken, and no amount of "apply the login styling"
   fixes it, because the login styling is exactly what is causing it.

   So: inside a card, .kc-form stops being a card and becomes its CONTENT. The panel already
   supplies the white, the border, the radius and the padding — the form supplies the field
   treatment, which is the part worth having. Standing alone (the login screen, the public
   quote form) nothing changes.
   ===================================================================================== */
.kc-card:not(.kc-editor) > .kc-form,
.kc-card:not(.kc-editor) > form.kc-form,
.kc-fold-body > .kc-form {
  max-width: 100%; background: none; border: 0; box-shadow: none;
  border-radius: 0; padding: 0; margin: 0;
}

/* THE EDITOR IS THE LOGIN SCREEN (2026-08-18, Zina: "they are not the same size, not
   centred and not on a white background"). Two ways to remove a card from inside a card:
   flatten the form, or flatten the PANEL. For an editor the second is right, because what
   she has been asking for all along is the login screen — a white card of a readable width,
   centred, standing on the page's own cream. So the panel gives up its chrome and becomes a
   plain centred column; the FORM is the card, exactly as it is on /login. */
.kc-editor { background: none; border: 0; box-shadow: none; padding: 0; }
.kc-editor > * { max-width: 32rem; margin-left: auto; margin-right: auto; }
.kc-editor > h3 { text-align: center; margin-bottom: .35rem; }
.kc-editor > .kc-note { text-align: center; margin-bottom: 1.1rem; }
.kc-editor .kc-form { max-width: 32rem; box-sizing: border-box; margin-left: auto; margin-right: auto; }

/* TWO COLUMNS WHERE THERE IS ROOM (2026-08-18, Zina: "yes please do 2 column forms where
   possible, bearing in mind always always do everything mobile responsive").

   MOBILE FIRST, and that is not a slogan here: everything above is the single-column card,
   so a phone gets the login layout with no second column to collapse and nothing to go
   wrong. The second column is added only when the viewport can hold it, and the card widens
   with it — two columns inside a 32rem card would be two cramped columns, which is worse
   than one honest one.

   Anything that needs the full row says so: a textarea, a tickbox line (whose label is a
   sentence, not a field name), the action row, and any section band or note. */
@media (min-width: 880px) {
  .kc-editor > *,
  .kc-editor .kc-form,
  .kc-form--2col { max-width: 46rem; }
  .kc-editor .kc-form,
  .kc-form--2col {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px 1.5rem; align-items: start;
  }
  .kc-editor .kc-form > label:has(textarea),
  .kc-editor .kc-form > label.kc-check,
  .kc-editor .kc-form > .kc-form-actions,
  .kc-editor .kc-form > .kc-form-sec,
  .kc-editor .kc-form > p,
  .kc-form--2col > label:has(textarea),
  .kc-form--2col > label.kc-check,
  .kc-form--2col > .kc-form-actions,
  .kc-form--2col > .kc-form-sec,
  .kc-form--2col > p { grid-column: 1 / -1; }
}

/* And with the width back, a 14-field editor should not be 14 rows tall. Two columns on a
   wide screen — the same shape the Organisation panel has used since July — with the wide
   controls (textarea, checkbox rows, the action row) spanning both. */

/* --- v14 (2026-08-17, Zina: "the supplier submit a quote form … styled to match our
   login form — in the old system I see it has barely any styling").
   The public supplier surface was the last kaycie form still wearing the THEME's raw
   input styling: 195px grey boxes, no card, no focus ring, theme-sized labels. It could
   not be fixed with a bespoke block of CSS without adding a fourth form dialect, so it
   opts into .kc-form above — the same primitive the login card is built from — and this
   section only adds what a PUBLIC, logged-out, long form needs on top.

   THE <br> RULE IS A BUG FIX, NOT DECORATION.
   The native kaycie idiom is  <p><label>Text<br><input></label></p>.  With the theme's
   inline-block inputs that <br> did nothing visible, which is why it survived. Inside
   .kc-form the label is a block and the input is width:100% — so the <br> would draw an
   EMPTY LINE between every label and its field, i.e. reintroduce exactly the "blank
   lines on the forms" fault v9.4/v9.5 fixed for JetFormBuilder. Suppressing it at the
   primitive means no form has to change its markup to stay clean, now or later. */
/* ONE centred column, heading and card the same width — otherwise the card floats left
   inside a wider column and the page reads as two competing left edges. */
.kc-formwrap        { display: flex; justify-content: center; padding: .2rem 0 0; }
.kc-formwrap > *    { width: 100%; max-width: 37rem; min-width: 0; }
.kc-formwrap .kc-form { max-width: 100%; }

.kc-form > p        { margin: 0; }            /* the card's flex `gap` is the only spacing authority */
.kc-form label > br,
.kc-form > p > br   { display: none; }        /* see THE <br> RULE above */
.kc-form small.kc-note,
.kc-form label + small { display: block; margin-top: .3rem; font-size: .82rem; line-height: 1.45; }
.kc-form input[type=file] {
  width: 100%; box-sizing: border-box; background: var(--kc-bg); color: var(--kc-ink);
  border: 1px dashed var(--kc-line-mid); border-radius: var(--kc-radius-btn);
  padding: 10px 12px; font-size: .92rem; font-family: var(--kc-font); margin-top: .3rem;
}
.kc-form input[type=file]:focus { outline: none; border-color: var(--kc-primary); border-style: solid;
                                  box-shadow: 0 0 0 3px rgba(var(--kc-primary-rgb), .12); }

/* a band that groups a long form into readable sections ("Your business", "The quote") */
.kc-form-sec        { font-family: var(--kc-font-head); font-weight: 800; font-size: .74rem;
                      letter-spacing: .1em; text-transform: uppercase; color: var(--kc-muted-2);
                      margin: 0 0 -.15rem; }
/* The divider belongs to every band EXCEPT the first — and ":first-child" cannot say that
   here, because hidden inputs and the honeypot are the form's real first children. The
   sibling combinator asks the right question: "is there a band above me?" */
.kc-form-sec ~ .kc-form-sec { margin-top: .55rem; padding-top: .7rem; border-top: 1px solid var(--kc-line-soft); }

/* --public: the login screen's single, full-width call to action. Dashboard forms keep
   inline buttons — a full-width bar next to a table would read as a page action. */
.kc-form--public button[type=submit] { width: 100%; text-align: center; justify-content: center;
                                       padding: 14px 18px; font-size: 16.5px; border-radius: 12px; }

/* /supplier/ gateway: three ways in, each announced above its own card. Sized down from
   the theme's h3 (which rendered as big as the page title) to sit under the lede. */
.kc-route-h         { font-family: var(--kc-font-head); font-weight: 800; font-size: 1.05rem;
                      letter-spacing: -.01em; color: var(--kc-ink); margin: 1.6rem 0 .3rem; }
.kc-formwrap .kc-route-h:first-of-type { margin-top: .8rem; }
.kc-formwrap .kc-msg > p.kc-note { margin: 0 0 .7rem; }

/* the heading block above a public form card, echoing the login card's h1 + sub */
/* The block that opens a form: mark, name, one line of why (2026-08-18). Centred, like the
   sign-in screen — it is the same job, telling you where you are before asking anything. */
/* `margin: 0 0 1.35rem` here quietly reset the auto-centring inherited from
   `.kc-editor > *`, so the heading sat flush left while the card below it centred — the
   mismatch Zina spotted. The shorthand keeps `auto` on the sides. */
.kc-form-head        { text-align: center; margin: 0 auto 1.35rem; }
.kc-form-head h2,
.kc-form-head h3     { font-family: var(--kc-font-head); font-weight: 800; font-size: clamp(1.35rem, 3vw, 1.7rem);
                       letter-spacing: -.02em; color: var(--kc-ink); margin: 0 0 .4rem; }
.kc-form-head p      { margin: 0 auto; max-width: 34rem; color: var(--kc-muted); font-size: .92rem; line-height: 1.6; }
.kc-formmark,
.kc-formmark-img     { display: block; margin: 0 auto .7rem; }
.kc-formmark-img     { height: 42px; width: auto; border-radius: 8px; }
.kc-formwrap .kc-form-head h2 { font-size: clamp(1.5rem, 3.2vw, 1.95rem); }
.kc-formwrap .kc-form-head p  { font-size: .96rem; }

/* ============================================================================
   v13 — TOOL GRID (Zina 2026-08-16: "smaller blocks for each item… same style as
   the main home dashboard"). Tools regroup into compact cards, 2-4 across, instead
   of full-width stripes. OPT-IN per dashboard via a .kc-toolgrid wrapper; a tool
   whose inline form is OPEN spans the full row so the form gets real width.
   Sample: Programmes. Rolls out per dashboard after Zina eyeballs it.
   ========================================================================== */
.kc-toolgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
               gap: 12px; margin: 0 0 1.15rem; align-items: stretch; }
.kc-toolgrid > * { min-width: 0; }
.kc-toolgrid .kc-tool { flex-direction: column; align-items: flex-start; gap: .55rem;
                        height: 100%; margin: 0; }
.kc-toolgrid .kc-tool .kc-tool-main { width: 100%; }
.kc-toolgrid .kc-tool .kc-tool-note { font-size: .84rem; }
.kc-toolgrid .kc-tool .kc-tool-acts { margin-top: auto; }
/* an open inline form needs the whole row, not a 230px card */
.kc-toolgrid > :has(details[open]) { grid-column: 1 / -1; }
.kc-toolgrid > :has(details[open]) .kc-tool { height: auto; }

/* per-tool "How do I…?" link (Zina: each tool links straight to its how-to section) */
.kc-tool-help { display: inline-block; margin-top: .3rem; font-size: .8rem; font-weight: 700;
                color: var(--kc-gold-text); text-decoration: none; }
.kc-tool-help:hover { color: var(--kc-primary); }

/* The upgrade card (2026-08-18). The only locked door in kaycie, and it carries a label:
   what the feature is, which package it belongs to, and that nothing already recorded is
   affected. A blank space would read as broken software. Deliberately NOT alarming — gold
   eyebrow, ordinary card — because a charity that has not bought something has done nothing
   wrong. */
.kc-upsell            { border-left: 3px solid var(--kc-gold); }
.kc-upsell-eyebrow    { font-family: var(--kc-font-head); font-size: .68rem; font-weight: 800;
                        letter-spacing: .1em; text-transform: uppercase; color: var(--kc-gold-text);
                        margin-bottom: .3rem; }
.kc-upsell h3         { margin: 0 0 .35rem; }
.kc-upsell .kc-note   { max-width: 42rem; }

/* start-here card: an empty main list becomes an invitation, not a shrug */
.kc-start { display: flex; align-items: center; gap: .9rem; background: #fff;
            border: 1.5px dashed var(--kc-line-mid); border-radius: var(--kc-radius);
            padding: 1.1rem 1.2rem; }
.kc-start .kc-btn { flex: none; }
.kc-start-t { font-family: var(--kc-font-head); font-weight: 700; color: var(--kc-ink); }
.kc-start-s { font-size: .86rem; color: var(--kc-muted); margin-top: .1rem; }

/* sortable headers + the list honesty line (UX batch 2026-08-16) */
table.kc-list thead th:not(.kc-col-actions) { cursor: pointer; user-select: none; }
table.kc-list thead th[aria-sort]::after { content: " \2191"; font-size: .75em; color: var(--kc-muted); }
table.kc-list thead th[aria-sort="descending"]::after { content: " \2193"; }
.kc-list-more { font-size: .87rem; color: var(--kc-muted); margin: .55rem 0 0; }
.kc-list-more a { color: var(--kc-primary); font-weight: 700; }

/* how-to page navigation (2026-08-17): the way back + the by-dashboard index,
   injected by Core so the live page needs no hand edits */
.kc-howto-back { position: sticky; top: .6rem; z-index: 40; margin: 0 0 1rem; }
.kc-howto-toc  { display: flex; flex-wrap: wrap; gap: .45rem; margin: 0 0 1.4rem; }
.kc-howto-toc .kc-btn { font-size: .84rem; }

/* ============================================================================
   demo player + guided tours (2026-08-17) — the spotlight and the narration
   bubble. The engine (kc-demo.js) drives the REAL form; these just light it.
   ========================================================================== */
.kc-demo-hi { position: absolute; z-index: 9998; pointer-events: none; border-radius: 12px;
              border: 2px solid var(--kc-gold, #e0a23c);
              box-shadow: 0 0 0 4px rgba(var(--kc-primary-rgb,124,10,39), .18),
                          0 0 0 9999px rgba(45, 2, 19, .45);
              transition: top .3s ease, left .3s ease, width .3s ease, height .3s ease; }
.kc-demo-bubble { position: absolute; z-index: 9999; max-width: 22rem; background: #fff;
                  border: 1px solid var(--kc-line, #efe1dc); border-radius: 14px;
                  box-shadow: 0 14px 40px -18px rgba(45,2,19,.4); padding: .85rem 1rem .7rem;
                  font-size: .92rem; line-height: 1.5; }
.kc-demo-eyebrow { font-size: .68rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
                   color: var(--kc-gold-text, #a86a12); margin-bottom: .3rem; }
.kc-demo-say { color: var(--kc-ink, #2d0213); }
.kc-demo-row { display: flex; align-items: center; justify-content: space-between; gap: .6rem; margin-top: .65rem; }
.kc-demo-dots { display: inline-flex; gap: .25rem; }
.kc-demo-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--kc-line-mid, #e7d6d0); }
.kc-demo-dot--on { background: var(--kc-primary, #7c0a27); }
.kc-demo-btns { display: inline-flex; gap: .35rem; }
.kc-demo-b { border: 1px solid var(--kc-line-mid, #e7d6d0); background: #fff; border-radius: 8px;
             font: inherit; font-size: .82rem; font-weight: 700; padding: .3rem .7rem; cursor: pointer;
             color: var(--kc-ink, #2d0213); }
.kc-demo-b--main { background: var(--kc-primary, #7c0a27); border-color: var(--kc-primary, #7c0a27); color: #fcf7f4; }
.kc-demo-b:hover { border-color: var(--kc-primary, #7c0a27); }
.kc-demo-launch { cursor: pointer; }

/* Per-dashboard walk-through launchers (2026-08-18, Zina: "can we add the walk through
   links straight onto the dashboards too please?"). A quiet strip under the back-link —
   present for whoever is stuck, ignorable for everyone who isn't. Injected by Core, so no
   dashboard carries it in its own HTML. */
.kc-journeys        { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem;
                      margin: 0 0 1.15rem; }
.kc-journeys-label  { font-family: var(--kc-font-head); font-size: .72rem; font-weight: 800;
                      letter-spacing: .09em; text-transform: uppercase; color: var(--kc-muted-2);
                      margin-right: .15rem; }
.kc-journeys .kc-btn { font-size: .82rem; padding: .38rem .8rem; }
@media (max-width: 560px) {
  .kc-journeys { gap: .35rem; }
  .kc-journeys .kc-btn { font-size: .78rem; }
}

/* JOURNEY steps that talk about the PAGE rather than a field (2026-08-18): no spotlight,
   so the narration takes the middle of the screen and grows a little to carry more copy —
   this is the "you're on Giving now, here's what you're looking at" beat. */
.kc-demo-bubble--mid { max-width: 30rem; padding: 1.1rem 1.25rem .9rem;
                       box-shadow: 0 22px 60px -18px rgba(45,2,19,.5);
                       border-left: 4px solid var(--kc-gold, #e0a23c); }
.kc-demo-bubble--mid .kc-demo-say { font-size: 1.02rem; line-height: 1.6; }

/* "one thing first" — a demo asked for on an empty install (2026-08-17). Centred card,
   no spotlight: there is nothing to spotlight yet, and pretending otherwise would be the
   lie the guard exists to prevent. */
.kc-demo-notyet { position: fixed; z-index: 9999; left: 50%; top: 22%; transform: translateX(-50%);
                  width: min(24rem, calc(100vw - 2rem)); background: #fff;
                  border: 1px solid var(--kc-line, #efe1dc); border-radius: 14px;
                  box-shadow: 0 18px 50px -20px rgba(45,2,19,.45); padding: 1rem 1.1rem .8rem;
                  font-size: .93rem; line-height: 1.55; }
.kc-demo-notyet .kc-demo-say { color: var(--kc-ink, #2d0213); }
