/* ============================================================================
   Page Polish — Login, Events, Members Directory
   Design token-based styling for non-profile pages
   ============================================================================ */

/* ============================================================================
   00. SECTION: Universal widget aspect-ratio safety (S82 2026-05-01 Rob)
   Standing rule per Rob: every widget content image MUST preserve its
   natural aspect ratio when its containing cell is resized. The cell can
   grow / shrink, but the image inside never stretches.

   Strategy: any <img> inside any .profile-widget* / .widget-body / .widget-
   content gets object-fit: contain by default (preserves ratio). Specific
   widgets that need cover-style cropping (photos gallery, sigil avatars
   with their natural square 1:1 ratio) override this further down with
   their own object-fit: cover rule.

   The width/height auto + max-100% pattern lets the image scale up to fill
   whichever dimension is smaller, so a wide cell with a tall logo gets
   centred letterboxing rather than stretched glyphs.
   ============================================================================ */
.profile-widget img,
.profile-widget-public img,
.widget-body img,
.widget-content img,
.party-logo-body img {
    object-fit: contain;
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
}
/* Sigil avatar pattern (venue / organiser / event) — circular crop is
   the intent, so cover wins here. Existing S77 rule in profile-system.php
   sigil_badge_css block already handles this with !important; rule below
   is belt-and-braces in case that block is missing on a render path. */
.profile-widget--sigil .profile-sigil-body img {
    object-fit: cover;
}
/* Photos / gallery widget — crop-to-fill is the photographic convention. */
.profile-widget .photo-panel img,
.profile-widget-public .photo-panel img,
.profile-widget .widget-photos img,
.profile-widget-public .widget-photos img,
.profile-widget .gallery-photo img,
.profile-widget-public .gallery-photo img {
    object-fit: cover;
    width: 100%;
    height: 100%;
    max-width: none;
    max-height: none;
}
/* end of 00 */

/* ============================================================================
   0. SECTION: Global form-input text colour (S82 2026-05-01 Rob)
   Forces every typed value in <input> / <textarea> / <select> to brand navy
   instead of the user-agent / Seeko-parent grey. -webkit-autofill carve-out
   keeps autofilled values navy too (browsers paint autofill in their own
   yellow + grey otherwise). Placeholder stays subtle grey — only the typed
   value flips.
   ============================================================================ */
input[type="text"],
input[type="email"],
input[type="password"],
input[type="search"],
input[type="tel"],
input[type="url"],
input[type="number"],
input[type="date"],
input[type="datetime-local"],
input[type="month"],
input[type="time"],
input[type="week"],
textarea,
select {
    color: #031B83 !important;
}
/* -webkit-autofill paints text in user-agent grey unless we force-fill */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active,
textarea:-webkit-autofill {
    -webkit-text-fill-color: #031B83 !important;
    caret-color: #031B83 !important;
}
/* end of 0 */

/* ============================================================================
   1. SECTION: Login Page (wp-login.php)
   ============================================================================ */
/* wp-login.php styles are handled by inline CSS in functions.php section 12.1.
   Do NOT add body.login rules here — they conflict with the inline !important styles. */
/* end of 1 */

/* ============================================================================
   2. SECTION: Events Page Cards
   ============================================================================ */

/* 2.1 Event card grid */
.events-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: var(--space-xl, 24px);
}

/* 2.1.0 P2.33a — events grid mobile/tablet adaptation
   Drop minmax floor to 260px between 481-768px to prevent overflow,
   single-column under 480px (smallest phone). */
@media (max-width: 768px) {
    .events-card-grid {
        grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
        gap: var(--space-md, 16px);
    }
}
@media (max-width: 480px) {
    .events-card-grid {
        grid-template-columns: 1fr;
    }
}

/* 2.1.1 Event card */
/* 2.1.1.1 Event card base style */
.event-card {
    position: relative;
    background: var(--color-surface, #FFFFFF);
    border-radius: var(--radius-lg, 12px);
    box-shadow: var(--shadow-sm, 0 1px 3px rgba(26, 26, 46, 0.08));
    overflow: hidden;
    transition: box-shadow var(--motion-normal, 200ms) cubic-bezier(0.16, 1, 0.3, 1),
                transform var(--motion-normal, 200ms) cubic-bezier(0.16, 1, 0.3, 1);
}
/* end of 2.1.1.1 */

/* 2.1.1.2 Event card hover lift */
.event-card:hover {
    box-shadow: var(--shadow-md, 0 4px 12px rgba(26, 26, 46, 0.12));
    transform: translateY(-2px);
}
/* end of 2.1.1.2 */
/* end of 2.1.1 */

/* 2.1.2 Hero image */
/* 2.1.2.1 Hero image container */
.event-card-hero {
    position: relative;
    height: 180px;
    overflow: hidden;
}
/* end of 2.1.2.1 */

/* 2.1.2.2 Hero image element fill */
.event-card-hero img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
/* end of 2.1.2.2 */

/* 2.1.2.3 Hero bottom gradient overlay */
.event-card-hero::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 60px;
    background: linear-gradient(to top, rgba(3, 27, 131, 0.4) 0%, transparent 100%);
    pointer-events: none;
}
/* end of 2.1.2.3 */
/* end of 2.1.2 */

/* 2.1.3 Date badge */
/* 2.1.3.1 Date badge container */
.event-card-date {
    position: absolute;
    top: var(--space-md, 12px);
    right: var(--space-md, 12px);
    background: var(--color-surface, #FFFFFF);
    border-radius: var(--radius-md, 8px);
    padding: var(--space-xs, 4px) var(--space-sm, 8px);
    text-align: center;
    box-shadow: var(--shadow-sm, 0 1px 3px rgba(26, 26, 46, 0.08));
    min-width: 48px;
}
/* end of 2.1.3.1 */

/* 2.1.3.2 Date badge day numeral */
.event-card-date-day {
    font-family: var(--font-heading, 'Montserrat', sans-serif);
    font-weight: 700;
    font-size: 22px;
    color: var(--color-navy, #031B83);
    line-height: 1;
    display: block;
}
/* end of 2.1.3.2 */

/* 2.1.3.3 Date badge month label */
.event-card-date-month {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    color: var(--color-gold, #CC9900);
    letter-spacing: 0.5px;
    display: block;
}
/* end of 2.1.3.3 */
/* end of 2.1.3 */

/* 2.1.4 Card body */
/* 2.1.4.1 Card body padding */
.event-card-body {
    padding: var(--space-lg, 16px);
}
/* end of 2.1.4.1 */

/* 2.1.4.2 Card title */
.event-card-title {
    font-family: var(--font-heading, 'Montserrat', sans-serif);
    font-weight: 700;
    font-size: 18px;
    color: var(--color-navy, #031B83);
    margin: 0 0 var(--space-sm, 8px) 0;
    line-height: 1.3;
}
/* end of 2.1.4.2 */

/* 2.1.4.3 Card venue line */
.event-card-venue {
    display: flex;
    align-items: center;
    gap: var(--space-xs, 4px);
    font-size: 14px;
    color: var(--color-text-muted, #6B7280);
    margin-bottom: var(--space-md, 12px);
}
/* end of 2.1.4.3 */

/* 2.1.4.4 Card venue dashicon */
.event-card-venue .dashicons {
    font-size: 14px;
    width: 14px;
    height: 14px;
    color: var(--color-gold, #CC9900);
}
/* end of 2.1.4.4 */
/* end of 2.1.4 */

/* 2.1.5 Attendee avatar stack */
/* 2.1.5.1 Card footer flex container */
.event-card-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
}
/* end of 2.1.5.1 */

/* 2.1.5.2 Attendees row container */
.event-card-attendees {
    display: flex;
    align-items: center;
}
/* end of 2.1.5.2 */

/* 2.1.5.3 Attendee avatar images */
.event-card-attendees img {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    border: 2px solid var(--color-surface, #FFFFFF);
    object-fit: cover;
    margin-left: -8px;
}
/* end of 2.1.5.3 */

/* 2.1.5.4 Attendee first-child margin reset */
.event-card-attendees img:first-child {
    margin-left: 0;
}
/* end of 2.1.5.4 */

/* 2.1.5.5 Attendees overflow count chip */
.event-card-attendees-more {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--color-surface-raised, #F9F8F5);
    border: 2px solid var(--color-surface, #FFFFFF);
    margin-left: -8px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
    font-weight: 700;
    color: var(--color-text-muted, #6B7280);
}
/* end of 2.1.5.5 */
/* end of 2.1.5 */

/* 2.1.6 RSVP button */
/* 2.1.6.1 RSVP button base style */
.event-card-rsvp {
    display: inline-flex;
    align-items: center;
    padding: var(--space-xs, 4px) var(--space-md, 12px);
    background: var(--color-gold, #CC9900);
    color: #031B83; /* S47: D055 — gold bg = blue text */
    border-radius: var(--radius-md, 8px);
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
    transition: background var(--motion-fast, 150ms) var(--motion-ease, cubic-bezier(0.16, 1, 0.3, 1));
}
/* end of 2.1.6.1 */

/* 2.1.6.2 RSVP button hover */
.event-card-rsvp:hover {
    background: var(--color-gold-dark, #80641D);
    color: #031B83; /* S47: D055 */
}
/* end of 2.1.6.2 */
/* end of 2.1.6 */

/* 2.2 Filter bar */
/* 2.2.1 Filter bar container — flex row, scroll */
.events-filter-bar {
    display: flex;
    gap: var(--space-sm, 8px);
    overflow-x: auto;
    padding-bottom: var(--space-md, 12px);
    margin-bottom: var(--space-xl, 24px);
    -webkit-overflow-scrolling: touch;
}
/* end of 2.2.1 */

/* 2.2.2 Filter bar — hide webkit scrollbar */
.events-filter-bar::-webkit-scrollbar {
    display: none;
}
/* end of 2.2.2 */

/* 2.2.3 Filter pill base style */
.events-filter-pill {
    display: inline-flex;
    align-items: center;
    padding: var(--space-xs, 4px) var(--space-md, 12px);
    border-radius: 9999px;
    border: 1px solid var(--color-border, #E5E7EB);
    background: var(--color-surface, #FFFFFF);
    color: var(--color-text, #1A1A2E);
    font-size: 14px;
    font-weight: 500;
    white-space: nowrap;
    cursor: pointer;
    transition: all var(--motion-fast, 150ms) var(--motion-ease, cubic-bezier(0.16, 1, 0.3, 1));
}
/* end of 2.2.3 */

/* 2.2.4 Filter pill hover */
.events-filter-pill:hover {
    background: var(--color-cream, #FFFBE6);
    border-color: var(--color-gold, #CC9900);
    color: var(--color-navy, #031B83);
}
/* end of 2.2.4 */

/* 2.2.5 Filter pill active */
.events-filter-pill.active {
    background: var(--color-gold, #CC9900);
    border-color: var(--color-gold, #CC9900);
    color: #031B83; /* S47: D055 — gold bg = blue text */
}
/* end of 2.2.5 */
/* end of 2.2 */

/* 2.3 Empty state */
/* 2.3.1 Empty state container */
.events-empty-state {
    text-align: center;
    padding: var(--space-3xl, 48px) var(--space-xl, 24px);
    color: var(--color-text-muted, #6B7280);
}
/* end of 2.3.1 */

/* 2.3.2 Empty state dashicon */
.events-empty-state .dashicons {
    font-size: 48px;
    width: 48px;
    height: 48px;
    opacity: 0.3;
    margin-bottom: var(--space-md, 12px);
}
/* end of 2.3.2 */

/* 2.3.3 Empty state paragraph */
.events-empty-state p {
    font-size: 16px;
    margin: 0;
}
/* end of 2.3.3 */
/* end of 2.3 */

/* 2.10 Search/filter row — centre the Search button + Reset link */
/* 2.10.1 Filter row secondary — flex centre */
.events-filter-row-secondary {
    display: flex !important;
    justify-content: center !important;
    align-items: center !important;
    gap: 12px;
    margin-top: 12px;
}
/* end of 2.10.1 */

/* 2.10.2 Filter button base style */
.events-filter-button {
    background: #fffbe6 !important;
    color: #031B83 !important;
    border: 2px solid #CC9900 !important;
    border-radius: 10px !important;
    padding: 8px 24px !important;
    font-weight: 600 !important;
    cursor: pointer;
    box-shadow: var(--shadow-gold-hover) !important;
}
/* end of 2.10.2 */

/* 2.10.3 Filter button hover */
.events-filter-button:hover {
    /* S207 05/09/26, Rob item A4: hover fills with the DARKER cream, not gold. */
    background: var(--color-cream-hover, #FFF5CC) !important;
    color: #031B83 !important;
    border-color: #CC9900 !important;
}
/* end of 2.10.3 */
/* end of 2.10 */

/* 2.11 Kill Seeko theme-static.min.css margin-bottom: 1rem on form inputs
   inside event/organiser/venue filter rows. Needs type-attribute selector
   to match Seeko's specificity: input[type=text] { margin-bottom: 1rem } */
.events-filter-row input[type=text],
.events-filter-row select,
.events-filter-row button { margin-bottom: 0 !important; }
/* end of 2 */

/* ============================================================================
   3. SECTION: Members Directory
   ============================================================================ */

/* 3.1 Member card grid */
.members-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: var(--space-xl, 24px);
}

/* 3.1.1 Member card */
/* 3.1.1.1 Member card base style */
.member-card {
    background: var(--color-surface, #FFFFFF);
    border-radius: var(--radius-lg, 12px);
    box-shadow: var(--shadow-sm, 0 1px 3px rgba(26, 26, 46, 0.08));
    padding: var(--space-xl, 24px);
    text-align: center;
    position: relative;
    overflow: hidden;
    transition: box-shadow 200ms cubic-bezier(0.16, 1, 0.3, 1),
                transform 200ms cubic-bezier(0.16, 1, 0.3, 1);
}
/* end of 3.1.1.1 */

/* 3.1.1.2 Member card hover lift */
.member-card:hover {
    box-shadow: var(--shadow-md, 0 4px 12px rgba(26, 26, 46, 0.12));
    transform: translateY(-2px);
}
/* end of 3.1.1.2 */
/* end of 3.1.1 */

/* 3.1.2 View profile overlay */
/* 3.1.2.1 Overlay container */
.member-card-overlay {
    position: absolute;
    inset: 0;
    background: rgba(3, 27, 131, 0.85);
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    transition: opacity 200ms cubic-bezier(0.16, 1, 0.3, 1);
    border-radius: var(--radius-lg, 12px);
}
/* end of 3.1.2.1 */

/* 3.1.2.2 Overlay reveal on card hover */
.member-card:hover .member-card-overlay {
    opacity: 1;
}
/* end of 3.1.2.2 */

/* 3.1.2.3 Overlay link button */
.member-card-overlay a {
    color: #CC9900; /* S47: D055 — blue bg = gold text */
    font-family: var(--font-heading, 'Montserrat', sans-serif);
    font-weight: 600;
    font-size: 16px;
    text-decoration: none;
    padding: var(--space-sm, 8px) var(--space-xl, 24px);
    border: 2px solid #CC9900; /* S47: D055 — gold border on blue bg */
    border-radius: var(--radius-md, 8px);
    transition: background var(--motion-fast, 150ms) var(--motion-ease, cubic-bezier(0.16, 1, 0.3, 1));
}
/* end of 3.1.2.3 */

/* 3.1.2.4 Overlay link hover */
.member-card-overlay a:hover {
    background: rgba(255, 255, 255, 0.15);
}
/* end of 3.1.2.4 */
/* end of 3.1.2 */

/* 3.1.3 Avatar */
.member-card-avatar {
    width: 80px;
    height: 80px;
    border-radius: 50%;
    object-fit: cover;
    margin: 0 auto var(--space-md, 12px);
    border: 3px solid var(--color-surface-raised, #F9F8F5);
}

/* 3.1.3.1 T179: Gold circle for default gravatar avatars */
.member-card-avatar[src*="gravatar"],
img.avatar[src*="gravatar"] {
    background: var(--color-navy, #031B83) !important;
    border-color: var(--color-gold, #CC9900) !important;
}

/* 3.1.4 Name + badges */
/* 3.1.4.1 Member card name */
.member-card-name {
    font-family: var(--font-heading, 'Montserrat', sans-serif);
    font-weight: 700;
    font-size: 16px;
    color: var(--color-navy, #031B83);
    margin: 0 0 var(--space-xs, 4px) 0;
}
/* end of 3.1.4.1 */

/* 3.1.4.2 Member card personality pill */
.member-card-personality {
    display: inline-flex;
    padding: 2px 10px;
    border-radius: 9999px;
    background: var(--color-navy, #031B83);
    color: var(--color-gold, #CC9900);
    font-size: 12px;
    font-weight: 600;
    margin-bottom: var(--space-md, 12px);
}
/* end of 3.1.4.2 */
/* end of 3.1.4 */

/* 3.1.5 Interest tags */
/* 3.1.5.1 Interest tags container */
.member-card-interests {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs, 4px);
    justify-content: center;
}
/* end of 3.1.5.1 */

/* 3.1.5.2 Interest tag pill */
.member-card-interest-tag {
    display: inline-flex;
    padding: 2px 8px;
    border-radius: 9999px;
    background: var(--color-surface-raised, #F9F8F5);
    color: var(--color-text-muted, #6B7280);
    font-size: 12px;
}
/* end of 3.1.5.2 */
/* end of 3.1.5 */

/* 3.1.6 Compatibility score */
.member-card-compat {
    margin-top: var(--space-md, 12px);
    font-size: 13px;
    font-weight: 600;
    color: var(--color-gold, #CC9900);
}

/* 3.2 Search/filter bar */
/* 3.2.1 Filter bar container */
.members-filter-bar {
    display: flex;
    gap: var(--space-sm, 8px);
    flex-wrap: wrap;
    margin-bottom: var(--space-xl, 24px);
    align-items: center;
}
/* end of 3.2.1 */

/* 3.2.2 Search input base style */
/* S222 14/09/26, Rob: "the search bar input field is way too wide. I'm trying to get you to reduce
   some of the sizes here. It's just ridiculous how wide that is." The members directory's field is
   BuddyPress's own #members_search inside #members-dir-search, not .members-search-input, so the
   rule below it never reached this page. Measured 337.70px at 1280; 220px is the same 35 percent
   reduction he asked for on the venue search, and the placeholder and magnifier still fit. */
/* the form was a block 337.70px wide, so narrowing the field alone left its magnifier stranded
   75.70px away; it becomes a centred row only as wide as the two things in it. */
#buddypress #members-dir-search #search-members-form {
    /* S227 15/09/26, Rob: "the magnifying glass icon should still be in the search input field
       next to the placeholder word search, it's odd that that's been done." S222 made this a
       flex ROW so the button sat beside the field in its own column. The row is what put it
       there, so the row goes: the form is a block exactly as wide as the 220px field, which is
       the containing block the magnifier is absolutely positioned inside (25.2.7). */
    display: block !important;
    width: 220px !important;
    max-width: 100% !important;
    margin: 0 auto;
    position: relative !important;
}
/* S222 moved the magnifier out of the field and into the flex row beside it. Rob rejected that
   on 14/09/26 on a real phone. The S222 rule that did it (position:static; margin:0) is REMOVED
   rather than overridden, so 25.2.7 - the one correct rule for this button - applies again and
   the icon sits 6px inside the field's right edge, vertically centred. The field keeps the 220px
   width he asked for in S222. */
#buddypress #members-dir-search #members_search {
    margin-right: 0 !important;
    margin-bottom: 0 !important;
}
#buddypress #members-dir-search #members_search,
#buddypress .dir-search input[type="text"] {
    width: 220px !important;
    max-width: 100% !important;
    flex: 0 1 220px !important;
}

.members-search-input {
    /* S222 14/09/26, Rob: "the search bar input field is way too wide. I'm trying to get you to
       reduce some of the sizes here." Measured 337.70px at 1280. The 35 percent he asked for on the
       venue search brings it to 220px, which still holds the placeholder and the magnifier, and it
       stays flexible down to 160 on a phone. */
    flex: 0 1 220px;
    max-width: 220px;
    min-width: 160px;
    border: 1px solid var(--color-border, #E5E7EB);
    border-radius: var(--radius-md, 8px);
    padding: var(--space-sm, 8px) var(--space-md, 12px);
    font-family: var(--font-body, 'Nunito Sans', sans-serif);
    font-size: 14px;
    transition: border-color var(--motion-fast, 150ms) var(--motion-ease, cubic-bezier(0.16, 1, 0.3, 1));
}
/* end of 3.2.2 */

/* 3.2.3 Search input focus */
html[data-nav="kbd"] .members-search-input:focus {
    outline: none;
    border-color: var(--color-gold, #CC9900);
    box-shadow: 0 0 0 2px rgba(204, 153, 0, 0.15);
}
/* end of 3.2.3 */

/* 3.2.4 Filter pill base style */
.members-filter-pill {
    display: inline-flex;
    align-items: center;
    padding: var(--space-xs, 4px) var(--space-md, 12px);
    border-radius: 9999px;
    border: 1px solid var(--color-border, #E5E7EB);
    background: var(--color-surface, #FFFFFF);
    color: var(--color-text, #1A1A2E);
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    transition: all var(--motion-fast, 150ms) var(--motion-ease, cubic-bezier(0.16, 1, 0.3, 1));
}
/* end of 3.2.4 */

/* 3.2.5 Filter pill hover */
.members-filter-pill:hover {
    border-color: var(--color-gold, #CC9900);
}
/* end of 3.2.5 */

/* 3.2.6 Filter pill active */
.members-filter-pill.active {
    background: var(--color-gold, #CC9900);
    border-color: var(--color-gold, #CC9900);
    color: #031B83; /* S47: D055 — gold bg = blue text */
}
/* end of 3.2.6 */
/* end of 3.2 */

/* 3.3 Load more */
/* 3.3.1 Load more container */
.members-load-more {
    text-align: center;
    margin-top: var(--space-xl, 24px);
}
/* end of 3.3.1 */

/* 3.3.2 Load more button base */
.members-load-more button {
    background: transparent;
    border: 2px solid var(--color-gold, #CC9900);
    color: var(--color-gold, #CC9900);
    border-radius: var(--radius-md, 8px);
    padding: var(--space-sm, 8px) var(--space-2xl, 32px);
    font-family: var(--font-body, 'Nunito Sans', sans-serif);
    font-weight: 600;
    font-size: 14px;
    cursor: pointer;
    transition: all var(--motion-fast, 150ms) var(--motion-ease, cubic-bezier(0.16, 1, 0.3, 1));
}
/* end of 3.3.2 */

/* 3.3.3 Load more button hover */
/* S213 item 36 (A4: gold buttons become light cream, DARKER cream on hover and select). Was a
   solid gold fill. The resting state still uses GOLD text on transparent rather than the navy
   the rest of the button system uses, which is flagged to Rob rather than changed here. */
.members-load-more button:hover {
    background: var(--color-cream-hover, #FFF5CC);
    border-color: var(--color-gold, #CC9900);
    color: #031B83; /* D055 */
}
/* end of 3.3.3 */
/* end of 3.3 */

/* 3.4 BP members directory override — redesigned member cards */
/* 3.4.0.1 Members-list grid layout */
#buddypress #members-list {
    display: grid !important;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 20px;
    list-style: none;
    padding: 0;
}
/* end of 3.4.0.1 */

/* 3.4.0.2 "Active" prefix on activity timestamp */
/* S59 2026-04-15: BuddyPress core's livestamp.min.js strips the "Active " prefix
   when it rewrites the timestamp to moment.js format, leaving bare "a week ago"
   on each card. Rob wants "Active" back on every card, always. CSS ::before is
   the cleanest fix — no JS race, no flash, no hook on livestamp. */
#buddypress #members-list .item-meta .activity::before {
    content: 'Active ';
}
/* end of 3.4.0.2 */

/* 3.4.0.3 Background li card chrome */
#buddypress #members-list li {
    /* S59 2026-04-15: background card grey so the white foreground card reads distinctly against it (Rob 2026-04-15). !important because Seeko parent theme sets white on li with higher cascade priority. E5E7EB chosen over F3F4F6 so the grey is clearly visible against the white inner card, not a subtle tint. */
    background: #E5E7EB !important;
    border-radius: 16px;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
    padding: 28px 20px 22px;
    text-align: center;
    transition: all 250ms cubic-bezier(0.16, 1, 0.3, 1);
    /* Override Seeko/Bootstrap col constraints — grid handles sizing */
    max-width: 100% !important;
    flex: none !important;
    width: 100% !important;
    /* S58 2026-04-14 rev2: outer (background) card permanently navy, inner permanently gold — no hover swap (Rob: "hover state as permanent state") */
    border: 2px solid #031B83 !important;
    position: relative;
    overflow: visible;
}
/* end of 3.4.0.3 */

/* 3.4.0.4 li hover shadow */
#buddypress #members-list li:hover {
    box-shadow: 0 12px 24px rgba(0, 0, 0, 0.21) !important;
}
/* end of 3.4.0.4 */

/* 3.4.0.5 Kill Seeko animations on li + descendants */
/* Kill Seeko base animations — leave hover states free for our custom transforms */
#buddypress #members-list li,
#buddypress #members-list li * {
    animation: none !important;
}
/* end of 3.4.0.5 */

/* 3.4.0.6 li hover transform on directory + about-us */
/* S58 2026-04-14: background card hover = 50% of foreground growth (scale + translate). Higher specificity than the Seeko kill rule so the transform actually applies.
   S58 2026-04-15 rev2: Added body.page-id-926 so the rear-card hover fires on the About Us gallery too — matches foreground animation on both pages. */
body.directory.members #buddypress #members-list li:hover,
body.page-id-926 #buddypress #members-list li:hover {
    transform: translateY(-5px) scale(1.025) !important;
}
/* end of 3.4.0.6 */

/* 3.4.0.7 Title colour shift on li hover */
/* Gentle name colour shift on hover — the only hover feedback */
#buddypress #members-list li:hover .item-title a {
    color: #CC9900 !important;
}
/* end of 3.4.0.7 */

/* 3.4.1 Force vertical card layout — override Seeko's flex-row. S58 2026-04-14 rev2: inner foreground card permanently gold (outer li card = navy). No hover swap per Rob. */
/* 3.4.1.1 Item-container vertical flex layout */
#buddypress #members-list .item-container {
    display: flex !important;
    flex-direction: column !important;
    align-items: center !important;
    gap: 0 !important;
    padding-top: 16px !important;
    background: #FFFFFF !important;
    border: 2px solid #CC9900 !important;
    border-radius: 12px !important;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12) !important;
    transition: all 250ms cubic-bezier(0.16, 1, 0.3, 1) !important;
    padding-bottom: 16px !important;
    margin: 0 !important;
    width: 100% !important;
}
/* end of 3.4.1.1 */

/* 3.4.1.2 Item-container hover scale + shadow */
#buddypress #members-list li:hover .item-container {
    box-shadow: 0 24px 48px rgba(0, 0, 0, 0.42) !important;
    /* S58 2026-04-15: vertical translateY removed from foreground card per
       Rob — only scale on hover, no vertical lift. */
    transform: scale(1.05) !important;
}
/* end of 3.4.1.2 */

/* 3.4.1.3 Lock inner content — kill nested transforms */
/* S58 2026-04-14: Lock inner content — Seeko parent applies its own transform on .item-card causing it to animate vertically over the sigil on hover. Kill all nested transforms so only the parent .item-container animation applies. */
#buddypress #members-list li .item,
#buddypress #members-list li .item-card,
#buddypress #members-list li .item-title,
#buddypress #members-list li .item-meta,
#buddypress #members-list li .member-card-badges,
#buddypress #members-list li:hover .item,
#buddypress #members-list li:hover .item-card,
#buddypress #members-list li:hover .item-title,
#buddypress #members-list li:hover .item-meta,
#buddypress #members-list li:hover .member-card-badges {
    transform: none !important;
    animation: none !important;
    transition: color 150ms ease !important;
}
/* end of 3.4.1.3 */
/* end of 3.4.1 */

/* 3.4.2 Avatar area — centred with gold ring */
/* 3.4.2.1 Avatar wrapper size */
#buddypress #members-list .item-avatar {
    width: 110px !important;
    height: 110px !important;
    margin: 0 auto 0 !important;
    flex-shrink: 0;
    position: relative;
}
/* end of 3.4.2.1 */

/* 3.4.2.2 Avatar link with gold gradient ring */
#buddypress #members-list .item-avatar a {
    display: block;
    width: 110px;
    height: 110px;
    border-radius: 50%;
    padding: 3px;
    background: linear-gradient(135deg, #CC9900 0%, #E6B800 50%, #CC9900 100%);
    box-shadow: 0 3px 12px rgba(0, 0, 0, 0.25);
    transition: box-shadow 250ms ease, transform 250ms ease;
    overflow: hidden !important;
}
/* end of 3.4.2.2 */

/* 3.4.2.3 Avatar hover gold glow */
/* Subtle gold glow on avatar hover — no movement */
#buddypress #members-list li:hover .item-avatar a {
    box-shadow: 0 3px 14px rgba(0, 0, 0, 0.3) !important;
}
/* end of 3.4.2.3 */

/* 3.4.2.4 Avatar figure — override Seeko aspect-ratio */
/* Override Seeko's aspect-ratio figure */
#buddypress #members-list .item-avatar figure,
#buddypress #members-list .item-avatar figure.img-dynamic,
#buddypress #members-list .item-avatar figure.aspect-ratio {
    width: 104px !important;
    height: 104px !important;
    margin: 0 !important;
    padding: 0 !important;
    border-radius: 50% !important;
    overflow: hidden !important;
    position: relative !important;
    /* Kill Seeko's aspect-ratio padding hack */
    padding-bottom: 0 !important;
    /* Prevent gold gradient bleed-through from parent link */
    background: #FFFFFF !important;
}
/* end of 3.4.2.4 */

/* 3.4.2.5 Avatar figure pseudo-elements — hide */
#buddypress #members-list .item-avatar figure::before,
#buddypress #members-list .item-avatar figure::after {
    display: none !important;
}
/* end of 3.4.2.5 */

/* 3.4.2.6 Avatar img sizing + reset */
#buddypress #members-list .item-avatar img {
    width: 104px !important;
    height: 104px !important;
    border-radius: 50% !important;
    object-fit: cover !important;
    display: block !important;
    margin: 0 !important;
    position: relative !important;
    top: auto !important;
    left: auto !important;
    transform: none !important;
}
/* end of 3.4.2.6 */

/* 3.4.2.7 Default avatar (no custom sigil) — navy bg */
/* Default avatar (no custom sigil) — navy background for premium feel */
#buddypress #members-list .item-avatar img[src*="mystery-man"],
#buddypress #members-list .item-avatar img[src*="bp-default"],
#buddypress #members-list .item-avatar img[src*="mystery"],
#buddypress #members-list .item-avatar img[src*="gravatar.com"] {
    /* S219 (Rob 10/09/26, CUST-124): the Account person in gold on the Default Sigil gradient. A real
       photo is opaque and covers both layers, so the person only ever shows on a placeholder. */
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='3.75 4.19 16.5 17.8'%3E%3Cpath d='M4.6 21.14c0-4.1 3.3-6.6 7.4-6.6s7.4 2.5 7.4 6.6z' fill='%23CC9900'/%3E%3Ccircle cx='12' cy='8.74' r='3.7' fill='%23CC9900'/%3E%3C/svg%3E") center 50% / 46% no-repeat, linear-gradient(145deg, #041D88 0%, #0A2A9E 100%);
}
/* end of 3.4.2.7 */
/* end of 3.4.2 */

/* 3.4.3 Online status dot */
#buddypress #members-list li.is-online .item-avatar::after {
    content: '';
    position: absolute;
    bottom: 4px;
    right: 4px;
    width: 16px;
    height: 16px;
    background: #22C55E;
    border: 3px solid #FFFFFF;
    border-radius: 50%;
    z-index: 2;
    box-shadow: 0 1px 4px rgba(34, 197, 94, 0.4);
}

/* 3.4.4 Card text area — full width, centred */
/* 3.4.4.1 .item-card — white bg, full width centred */
/* S59 2026-04-15: force pure white bg. The lower portion of the foreground card
   (name + badges + attendance pill) is rendered by this element as an opaque
   child on top of .item-container. Seeko parent theme ships a cream bg on
   .item-card which was bleeding through and making the whole foreground look
   cream — proven by setting it magenta in Chrome MCP and watching the whole
   lower area turn magenta. Visually verified before landing this rule. */
#buddypress #members-list .item-card {
    width: 100% !important;
    text-align: center;
    padding-top: 10px !important;
    background: #FFFFFF !important;
}
/* end of 3.4.4.1 */

/* 3.4.4.2 .item — full width */
#buddypress #members-list .item {
    width: 100%;
}
/* end of 3.4.4.2 */

/* 3.4.4.3 Item title typography */
#buddypress #members-list .item-title {
    font-family: 'Montserrat', sans-serif;
    font-weight: 700;
    font-size: 15px;
    color: #031B83;
    margin: 0 0 2px;
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* end of 3.4.4.3 */

/* 3.4.4.4 Item title link colour + transition */
#buddypress #members-list .item-title a {
    color: inherit;
    text-decoration: none;
    transition: color 150ms ease;
}
/* end of 3.4.4.4 */

/* 3.4.4.5 Item title link gold on li hover */
#buddypress #members-list li:hover .item-title a {
    color: #CC9900;
}
/* end of 3.4.4.5 */

/* 3.4.4.6 Hide nickname / update spans inside title */
/* Hide status update and nickname text appended after display name */
#buddypress #members-list .item-title span.user-nicename,
#buddypress #members-list .item-title .nickname-text,
#buddypress #members-list .item-title span.update {
    display: none !important;
}
/* end of 3.4.4.6 */

/* 3.4.4.7 Item meta typography */
#buddypress #members-list .item-meta {
    font-size: 12px;
    color: #9CA3AF;
    margin: 0;
    letter-spacing: 0.01em;
}
/* end of 3.4.4.7 */
/* end of 3.4.4 */

/* 3.4.5 Action area — hidden on members directory (messaging requires mutual interest) */
#buddypress #members-list .action {
    display: none !important;
}

/* 3.4.6 Member card badges — membership level + pinned preference symbols */
/* 3.4.6.1 Badges container — vertical stack */
#buddypress #members-list .member-card-badges {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    margin-top: 12px;
    padding-top: 10px;
    border-top: 1px solid rgba(3, 27, 131, 0.06);
}
/* end of 3.4.6.1 */

/* 3.4.6.2 Symbol row — flex wrap */
#buddypress #members-list .member-card-symbols {
    display: flex;
    gap: 6px;
    justify-content: center;
    flex-wrap: wrap;
}
/* end of 3.4.6.2 */

/* 3.4.6.3 Symbol pill — circular */
#buddypress #members-list .member-symbol-pill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: rgba(3, 27, 131, 0.04);
    font-size: 16px;
    line-height: 1;
}
/* end of 3.4.6.3 */

/* 3.4.6.4 Membership level pill base */
#buddypress #members-list .member-card-level {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-family: 'Montserrat', sans-serif;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: #9CA3AF;
    padding: 3px 12px;
    border-radius: 9999px;
    background: rgba(3, 27, 131, 0.03);
    text-align: center;
    line-height: 1.4;
}
/* end of 3.4.6.4 */

/* 3.4.6.5 Level pill — free tint */
/* D-652 25/09/2026: cream/gold, matching 13.5.1 which wins the cascade on this same selector. */
#buddypress #members-list .member-card-level.level-free {
    color: var(--color-navy);
    background: var(--color-cream);
}
/* end of 3.4.6.5 */

/* 3.4.6.6 Level pill — standard tint */
#buddypress #members-list .member-card-level.level-standard {
    color: var(--color-navy);
    background: var(--color-cream);
}
/* end of 3.4.6.6 */

/* 3.4.6.7 Level pill — premium tint */
#buddypress #members-list .member-card-level.level-premium {
    color: var(--color-navy);
    background: var(--color-cream);
}
/* end of 3.4.6.7 */

/* 3.4.6.8 Level pill — organiser tint */
#buddypress #members-list .member-card-level.level-organiser {
    color: var(--color-navy);
    background: var(--color-cream);
}
/* end of 3.4.6.8 */

/* 3.4.6.9 Level pill — venue tint */
#buddypress #members-list .member-card-level.level-venue {
    color: var(--color-navy);
    background: var(--color-cream);
}
/* end of 3.4.6.9 */
/* end of 3.4.6 */

/* ============================================================================
   4. SECTION: Mobile Responsive — 360px floor (Nothing Phone 3a)
   ============================================================================ */

/* 4.1 Tablet breakpoint */
@media (max-width: 768px) {
    /* Event cards — single column on mobile */
    .events-card-grid {
        grid-template-columns: 1fr !important;
        gap: 16px;
    }

    .event-card-hero {
        height: 160px;
    }

    .event-card-title {
        font-size: 16px;
    }

    .event-card-body {
        padding: 12px;
    }

    /* Events filter bar — horizontal scroll, no wrap overflow */
    .events-filter-bar {
        gap: 6px;
        padding-bottom: 8px;
        margin-bottom: 16px;
    }

    .events-filter-pill {
        font-size: 13px;
        padding: 4px 10px;
    }

    /* Members directory — single column */
    .members-card-grid {
        grid-template-columns: 1fr !important;
        gap: 16px;
    }

    /* BP members directory — single column */
    #buddypress #members-list {
        grid-template-columns: 1fr !important;
        gap: 16px;
    }

    #buddypress #members-list li {
        padding: 20px 16px 18px;
    }

    /* Members filter bar — stack on mobile */
    .members-filter-bar {
        flex-direction: column;
        gap: 8px;
    }

    .members-search-input {
        min-width: 100%;
    }

    /* Member card avatar — slightly smaller on mobile */
    #buddypress #members-list .item-avatar {
        width: 90px !important;
        height: 90px !important;
        margin-bottom: 12px !important;
    }

    #buddypress #members-list .item-avatar a {
        width: 90px;
        height: 90px;
    }

    #buddypress #members-list .item-avatar figure,
    #buddypress #members-list .item-avatar figure.img-dynamic,
    #buddypress #members-list .item-avatar figure.aspect-ratio {
        width: 84px !important;
        height: 84px !important;
    }

    #buddypress #members-list .item-avatar img {
        width: 84px !important;
        height: 84px !important;
    }
}

/* 4.2 Extra small — 360px floor */
@media (max-width: 480px) {
    /* Reduce excessive container padding — 51px each side at 360px is too much */
    .events-page-wrapper {
        padding-left: 10px !important;
        padding-right: 10px !important;
    }

    /* Featured events — stack vertically instead of horizontal scroll */
    .events-featured-scroll {
        flex-direction: column !important;
        gap: 12px !important;
        overflow-x: visible !important;
    }

    .events-featured-scroll .event-card {
        min-width: 0 !important;
        flex-shrink: 1 !important;
        width: 100% !important;
    }

    /* Date badge — inline flow on small screens instead of absolute overlay */
    .event-card-date {
        position: static !important;
        display: block;
        text-align: center;
        margin-bottom: 8px;
        box-shadow: none; /* intentional: flatten date-badge shadow when position changes from absolute overlay to inline block at ≤480px (Phase 2a S65) */
    }

    /* Center section headings */
    .events-section-title {
        text-align: center;
    }

    /* Center submit button */
    .event-submit-link {
        display: block;
        margin: 0 auto 20px;
        text-align: center;
        width: fit-content;
    }

    /* Tighter padding on cards */
    .event-card-body {
        padding: 10px;
    }

    .event-card-title {
        font-size: 15px;
    }

    .event-card-rsvp {
        font-size: 12px;
        padding: 3px 10px;
    }

    #buddypress #members-list li {
        padding: 16px 12px 14px;
    }

    .member-card {
        padding: 20px 16px;
    }

    /* Prevent horizontal overflow globally */
    .events-card-grid,
    .members-card-grid,
    #buddypress #members-list {
        max-width: 100% !important;
        overflow-x: hidden !important;
    }

    /* Global page content — reduce padding for all shortcode pages */
    .entry-content {
        padding-left: 8px !important;
        padding-right: 8px !important;
    }
}

/* end of 3 + 4 */

/* 5. SECTION: About Us page — members grid (BUG-08).
   <!-- AMENDMENT v2.5 (2026-04-11): The Seeko members-grid Elementor widget
        wraps the BP loop in a display:flex container that gives 5-per-row at
        the About Us breakpoint, producing an awkward 5+3 layout with 8 cards.
        For the 8-card About Us grid we want a clean 4×2 layout. We honour
        Rob's "match /members/" intent by leaving the CARD interior styling
        completely untouched (avatar, name, badges, hover all inherit) and
        only nudging the row count. No padding, no max-width gymnastics, no
        margin tricks — just the flex-basis. -->
*/
/* 5.1 Members-list grid — vertical stack (T233) */
/* T233: 4 cards stacked vertically — single column, centered */
body.page-id-926 .uksp-widget-members-grid #members-list-grid {
    flex-direction: column !important;
    align-items: center !important;
    gap: 16px !important;
}
/* end of 5.1 */

/* 5.2 Members-list grid li — max 360px */
body.page-id-926 .uksp-widget-members-grid #members-list-grid > li {
    flex: 0 0 auto !important;
    max-width: 360px !important;
    width: 100% !important;
}
/* end of 5.2 */

/* 5.3 Members-list grid li — full width at <=480px */
@media (max-width: 480px) {
    body.page-id-926 .uksp-widget-members-grid #members-list-grid > li {
        max-width: 100% !important;
    }
}
/* end of 5.3 */
/* end of 5 */

/* 6. SECTION: Pricing page polish */

/* 6.1 TASK-NEW-11 (5b.1) — Pricing h1 brand colour
   The Pricing page heading widget has no color set in Elementor, so the
   .uksp-heading-title inherits from the theme default (#000/#111),
   rendering black instead of brand blue. Force brand blue #031B83 on
   page-id-439 headings so the title matches D055. */
body.page-id-439 .uksp-widget-heading .uksp-heading-title,
body.page-id-439 .uksp-element-b3512e4 .uksp-heading-title {
    color: #031B83 !important;
    /* 26/09 (Rob: "Check pricing again. It's obviously wrong, on both sizes"): the builder gave this title a 63px face on a
       23.4px line box, so the glyphs overflowed the box and the gold underline (D-670) ran through the letters. The title
       takes the Events page title's metrics exactly: 56.8px Montserrat 600 on a 1.2 line box, at every width. */
    font-size: 56.8px !important;
    line-height: 1.2 !important;
    font-weight: 600 !important;
}
/* end of 6.1 */

/* end of 6 */

/* ============================================================================
   7. SECTION: Venues & Organisers Directory pages
   ============================================================================ */

/* 7.1 Center directory header (heading + apply button) */
/* 7.1.1 Directory header text-align centre */
.directory-header {
    text-align: center;
}
/* end of 7.1.1 */

/* 7.1.2 Apply button auto-margin centring */
.directory-header .directory-apply-button {
    display: inline-block;
    margin-left: auto;
    margin-right: auto;
}
/* end of 7.1.2 */
/* 7.1.3 THE VENUES PAIR IS ONE WIDTH AT EVERY SIZE (S224 15/09/26, Rob's item 208)
   His words: "at 360 they should be the same width - the register button is slightly wider than
   the suggest button, so make the suggest button slightly wider to match. In fact, just double
   check, they should be the same width at every size."
   MEASURED BEFORE at 1280: Register Your Venue 182.97px against Suggest a Location 176.17px, so
   6.80px apart. The row is a flex line written inline in event-system.php, and flex has no way to
   size a child to its widest sibling. A grid with 1fr tracks inside a fit-content box does, so
   both buttons take the longer label's width and the row still centres. Same mechanism as the
   card pair, which Rob has already signed off. The 600 step is the one the inline rule already
   used for stacking; it is not one of his own breakpoints (D-529) and is left where it was
   rather than moved tonight. */
.venues-directory-actions {
    display: grid !important;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    width: fit-content;
    margin-left: auto;
    margin-right: auto;
    gap: 12px;
}
@media (max-width: 599.98px) {
    .venues-directory-actions { grid-auto-flow: row; }
}
/* end of 7.1.3 */
/* end of 7.1 */

/* 7.2 Reorder: button above heading, heading directly above search */
/* 7.2.1 Directory header — flex column */
.directory-header {
    display: flex !important;
    flex-direction: column !important;
    align-items: center !important;
}
/* end of 7.2.1 */

/* 7.2.2 Directory header h2 ordering + brand */
.directory-header h2 {
    order: 2 !important;
    margin-top: 0 !important;
    margin-bottom: 8px !important;
    font-family: 'Montserrat', sans-serif !important;
    color: #031B83 !important;
}
/* end of 7.2.2 */

/* 7.2.3 Apply button ordering */
.directory-header .directory-apply-button {
    order: 1 !important;
    margin-bottom: 12px !important;
}
/* end of 7.2.3 */

/* 7.2.4 Directory header with no title (S198 29/08/26, Rob).
   Where the redundant "<Thing> Directory" h2 has been removed, the header would
   otherwise collapse by the h2's full height plus its 8px margin and snap the
   filter bar ~51px further up than asked for. Rob's instruction was to bring the
   search "perhaps where the bottom of the venue directory font currently is", so
   this puts back exactly the gap needed to land the filter bar on that line.
   Value is measured against the live page, not chosen: with the h2 gone the header
   bottom sits at y=348 and the old h2 baseline was y=411.1, so the gap wanted was
   63px. It must be stated as one margin rather than split, because this margin and
   the filter section's own 33px margin-top COLLAPSE - only the larger applies, which
   is why a 30px value here changed nothing at all.
   48px = that line less the 5px, then a further 10px, both asked for on 29/08/26. */
.directory-header--no-title {
    margin-bottom: 26px !important;
}
/* item 118, 13/10/26, Rob: 60px gap at 1280 and above, the tighter 38px kept below */
@media (min-width: 1280px) {
    .directory-header--no-title {
        margin-bottom: 48px !important;
    }
}
/* end of 7.2.4 */
/* end of 7.2 */

/* 7.3 Single venue page — centre title block + indicators */
/* 7.3.1 Venue title block — centre text */
.venue-title-block {
    text-align: center !important;
}
/* end of 7.3.1 */

/* 7.3.2 Venue title — centre flex content */
.venue-title-block .venue-title {
    justify-content: center !important;
}
/* end of 7.3.2 */

/* 7.3.3 Venue hero meta — centre */
.venue-title-block .venue-hero-meta {
    justify-content: center !important;
}
/* end of 7.3.3 */

/* 7.3.4 Venue badge — inline-block */
.venue-title-block .venue-badge {
    display: inline-block !important;
}
/* end of 7.3.4 */
/* end of 7.3 */

/* 7.4 T221: Venue card content + addresses centered */
/* 7.4.1 Card body text centre */
.events-grid .event-card .event-card-body {
    text-align: center !important;
}
/* end of 7.4.1 */

/* 7.4.2 Card footer justify centre */
.events-grid .event-card .event-card-footer {
    justify-content: center !important;
}
/* end of 7.4.2 */
/* end of 7.4 */

/* end of 7 */

/* ============================================================================
   8. SECTION: Members directory mobile centering fix
   ============================================================================ */

/* 8.1 Remove Bootstrap negative margins that offset the grid left on mobile */
@media (max-width: 480px) {
    #buddypress #members-list {
        margin-left: 0 !important;
        margin-right: 0 !important;
        width: 100% !important;
    }
    /* Reduce excessive container padding on members page */
    body.page-id-13 .content-wrapper.container {
        padding-left: 10px !important;
        padding-right: 10px !important;
    }
    /* S217: found by the six-width sweep. This section already zeroes the Bootstrap gutter on
       #members-list, but the OUTER row still carried its -15px margins, and 10px of container
       padding cannot absorb 15px: the row measured 370px inside a 360px screen and the page
       scrolled sideways by 5px, with 5px of content clipped off each edge by body's hidden
       overflow. Zeroing it here is the same fix this section already applies one level down. */
    body.page-id-13 .content-wrapper.container > .row {
        margin-left: 0 !important;
        margin-right: 0 !important;
    }
}
/* end of 8 */

/* ============================================================================
   9. SECTION: Pricing page — reassurance card centering
   ============================================================================ */

/* 9.1 Center the "Before you think twice" text */
.pricing-reassurance-card {
    text-align: center;
}
/* end of 9 */

/* ============================================================================
   10. SECTION: About Us page — heading colour fix
   ============================================================================ */

/* 10.1 "Where Culture Meets Connection" heading should be brand blue */
body.page-id-926 .uksp-element-8972833 .uksp-heading-title {
    color: #031B83 !important;
    text-shadow: 0 2px 3px rgba(3, 27, 131, 0.22) !important;
}
/* end of 10 */

/* ============================================================================
   11. SECTION: Contact Us page fixes
   ============================================================================ */

/* 11.1 "Email Form" heading — brand blue */
body.page-id-3727 .uksp-element-83d05f1 .uksp-heading-title {
    color: #031B83 !important;
}

/* 11.2 Reduce dead space in form box */
body.page-id-3727 .uksp-element-ffe5566 {
    padding: 16px 16px 20px !important;
}

/* 11.3 T285: Reduce spacing in contacts box (links / QR) — tighter */
body.page-id-3727 .uksp-element-b913745 {
    padding: 8px 16px !important;
    gap: 8px !important;
}

/* FF02-12: Contact page uses the same flat contact block and navy title shadow
   verified in the prelaunch visual pass. */
body.page-id-3727 .uksp-element-a91862e h1 {
    text-shadow: 0 2px 3px rgba(3, 27, 131, 0.22) !important;
}
body.page-id-3727 .uksp-element-b913745 {
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
}
body.page-id-3727 .uksp-element-b913745 .uksp-element-bcf33c6 {
    margin-top: 16px !important;
}

/* 11.3.1 T285: Links closer to heading — reduce top margin */
body.page-id-3727 .uksp-element-b913745 .uksp-widget-text-editor {
    margin-top: 0 !important;
    padding-top: 0 !important;
}

/* 11.4 T285: Reduce gap between contacts box and woman image */
body.page-id-3727 .uksp-element-e156348 {
    gap: 4px !important;
    margin-top: 13px !important;   /* 11.12 (Rob 26/09, "use the events page as the reference"): 13px here plus the block's 8px padding and the list's own offset put the first link 39px under the title's underline, the Events page's figure; 9px at phone widths for its 33px */
    margin-bottom: 0 !important;
}
@media (max-width: 767px) {
    body.page-id-3727 .uksp-element-e156348 { margin-top: 9px !important; }
}

/* 11.5 T285: Reduce massive gap between image and form */
body.page-id-3727 .uksp-section .uksp-container > .uksp-column {
    margin-bottom: 8px !important;
}

/* 11.6 T285: Woman image centering */
body.page-id-3727 .uksp-element-e156348 img {
    display: block !important;
    margin: 0 auto !important;
}

/* 11.7 R3-34 (Rob, 24/09/2026): "put this whole contact us stuff on a panel with a gold border
   and a white background". The original painted a full-width white section, with the page
   background showing as a grey band above it on a phone and the form left outside it on the
   grey. The page wrapper is now the ONE panel, drawn like the platform's content cards
   (.workspace .card: white, 1.5px gold border, 16px corners, soft shadow) and set on the plain
   page background with a 16px gutter; the full-width section is see-through, so nothing inside
   paints a second surface, and the photo is held to the panel's width. */
body.page-id-3727 .uksp.uksp-3727 {
    box-sizing: border-box;
    width: calc(100% - 2 * var(--sp-lg));
    max-width: 1200px;
    margin: var(--sp-2xl) auto 0;
    padding-top: 21px;
    background: var(--color-surface);
    border: 1.5px solid var(--color-gold);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
}
/* 11.7.1 R3-34b (Rob, 25/09/2026): "the spacing looks a bit off ... too close to the top" and
   "the width should reflect the screen width ... not a really thin, narrow column ... on a
   1280". Measured live 25/09/2026: the panel's own max-width (1200px) and auto side margins
   already match .events-page-wrapper's own rule (max-width: 1200px; margin: 0 auto - the
   standard container /events/ and every other public page use), so at 1280 and 1920 the panel
   already spans the page the same way as the rest of the site; nothing to change there. The
   title gap did need fixing: measured on /members/<id>/account/ as jack, the dashboard cards'
   own title sits 28px below the card's top edge (24px padding-top, --sp-xl, plus ~4px of font
   overshoot above the 18px .card__title's own capital letters) at both 412 and 1280 alike - a
   fixed number, not one that changes by width. Here "Contact Us" was only 23px down at 412 but
   66px down at 1280/1920, because two page-builder wrappers inside the panel each carry their
   OWN responsive padding-top that is not ours to edit at its source (third-party CSS):
   .uksp-element-51af6730 (0 at mobile, 40px at tablet/desktop) and its child
   .uksp-element-5ee1d04 (16px mobile, 18px tablet/desktop). Both are scope-bumped to zero below
   and the panel itself (the item's own selector) now carries the one flat padding-top instead
   (21px), so there is a single non-responsive source for it. 21px, plus the panel's own ~1px
   border and the H1's own ~6-7px capital-letter overshoot (not paddings, left alone), lands the
   title at 28px down at every width measured, matching the dashboard cards. */
body.page-id-3727 .uksp-3727 .uksp-element.uksp-element-51af6730 {
    --width: 100%;
    --margin-top: 0rem;
    background-color: transparent;
    padding-top: 0;
}
body.page-id-3727 .uksp-3727 .uksp-element.uksp-element-5ee1d04 {
    padding-top: 0;
}
body.page-id-3727 .uksp-element-e156348 .uksp-element-a8441d9 img {
    width: 100%;
}
/* 11.7.2 R3-34d (Rob, 25/09/2026): "on the wider screen I have no idea why you've listed the
   details off to the left. They should be back where they were before ... so the picture of the
   woman and the contact details are equidistant from the centre of the screen." Measured live:
   the row (.uksp-element-e156348) carries no width cap of its own, so from 768px up it stretches
   to the panel's full content track (1118px at 1280/1920) and centres the Contacts block and the
   photo as a 1118px-wide PAIR rather than centring their ink - the Contacts text hugs the left of
   its own 500px column while the photo (11.7 above) fills its 500px column edge to edge, so the
   visible gap between them reads as pushed left. This scope-bumps the row itself (third-party
   page-builder width, not ours to edit at its source) to the same 660px the panel already uses
   elsewhere on this page for a single centred column (40.10.1), centred the same way (margin
   auto). The two columns already carry flex-shrink from the builder's own CSS (confirmed live: at
   the builder's own 800px breakpoint they already shrink together to fit a narrower row without
   any change here), so capping the row alone is enough: both columns shrink evenly from 500px to
   ~328px each and land flush with the row's own edges, making the Contacts block's left edge and
   the photo's right edge equidistant from the page centre by construction, not by a guessed
   number. No @media: the same flat rule that does nothing below 768px (the row is already
   narrower than 660px there) is what holds it at 1280 and 1920. */
body.page-id-3727 .uksp-element-e156348 {
    max-width: 660px !important;
    margin-left: auto !important;
    margin-right: auto !important;
}

/* 11.8 R3-34 (Rob 26/09/2026, with his screenshot): the contact form panel takes the same 660px as the row above it and
   the label panel between them (40.10.1), so the three share one width on every screen from 768 up; on a phone all three
   already fill the width. The form's 420px cap comes from the shared login-form width list in functions.php (an
   !important rule that also matches this form) and the wrapper's own 460px cap, so this page-scoped rule carries
   !important to be heard; the shared rules are not widened because the login and widget forms rely on them. */
body.page-id-3727 .contact-form-wrapper { max-width: 660px !important; }
body.page-id-3727 .contact-form-wrapper .organiser-apply-form { max-width: 660px !important; }

/* 11.9 R3-34 (Rob 26/09/2026, his screenshot): from 768 up the picture sits flush with the row's right edge, the
   same edge the label panel and the form share, so the Contacts block's left edge and the picture's right edge are the
   row's own edges. On a phone the row stacks and the picture stays centred (11.6). The new 300x300 picture (attachment
   7993, his file "Contact us 300 x 300 - comp.png") is narrower than its column, which is why 11.6's centring no longer
   put it on that edge. */
@media (min-width: 768px) {
    /* the picture's 300px wrapper sits inside a 322px flex column (.uksp-element-e240971, column direction) whose right
       edge IS the row's edge: align-items puts the wrapper on that edge, justify-content keeps it at the TOP beside the
       links, as in Rob's screenshot (measured 26/09: wrapper 648 to 948, column to 970) */
    body.page-id-3727 .uksp-element-e156348 .uksp-element-e240971 { justify-content: flex-start !important; align-items: flex-end !important; }
}
/* 11.10 R3-34 (Rob 26/09, his screenshot again): no "Contacts" subtitle above the links ("there's still the secondary
   'contacts' subtitle which should be removed"), and no dead space: the links list loses the 16px it kept for that
   heading, and the QR picture is the tight crop (attachment 7994: the old 169x300 jpg carried 265px of blank above the
   code and 237px below it at full size, which is what read as dead space between the links, the code and the woman).
   The heading's markup stays in the template and is hidden here, so it can come back with one line. */
body.page-id-3727 .uksp-element-e156348 .uksp-element-69228aa { display: none !important; }
body.page-id-3727 .uksp-element-e156348 .uksp-element-bcf33c6 { margin-top: 0 !important; }

/* 11.11 (Rob 26/09, his phone screenshot of the form): "make the drop down border the same as all the others". The
   Subject control is the events-page dropdown (.ev-dd__btn, a 2px gold ring there); inside this form its ring matches the
   inputs and the textarea, 1px. */
body.page-id-3727 .contact-form-wrapper .ev-dd__btn { border-width: 1px; }

/* 11.12 (Rob 26/09, five screenshots: "they should all be the same, the same gold underline, and the same space before
   content ... Use the events page as the reference"). Measured on the Events page: 39px from the title's underline to the
   first content at 1280, 33px at phone widths. Members (27/24) and Blog (28/28) take the same figures through their title
   margins; Contact through 11.12 above; Pricing through 11.13; Organisers, Venues and Public Locations already match. */
body.page-id-13 .entry-title.page-title { margin-bottom: 39px !important; }
body.blog .entry-title.page-title { margin-bottom: 39px !important; }
@media (max-width: 767px) {
    body.page-id-13 .entry-title.page-title { margin-bottom: 33px !important; }
    body.blog .entry-title.page-title { margin-bottom: 33px !important; }
}

/* 11.13 Pricing (Rob 26/09): 80px sat between the title's underline and the reassurance card at 1280 (71 at phone widths):
   the title block's 18px bottom padding, an empty paragraph the template carries (0px tall, 27px of margin) and the rest
   of the builder's spacing. The empty paragraph's margin goes and the title block's padding is trimmed so the card sits
   the Events page's 39px (33px on a phone) under the underline. */
body.page-id-439 .uksp-element-b2d7eb8 > p:has(> style) { margin: 0 !important; padding: 0 !important; }   /* the autop-wrapped inline style tag: a paragraph with nothing visible and 27px of margin */
body.page-id-439 .uksp-element-b3512e4 { padding-bottom: 3px !important; }
@media (max-width: 767px) {
    body.page-id-439 .uksp-element-b3512e4 { padding-bottom: 1.5px !important; }
}

/* 11.14 THE THREE GUIDES (S245 row 84, D-798, GUIDES-1; Rob 07/10/26: "there's a title panel underneath the actual page title - that's pointless ... it's
   not on style for the platform. It all needs to be centered with proper little subtitles and gold underline under subtitles ... And little gold spaces between the
   sections. You can take inspiration from the events pages."). The title panel is already gone from all three guides (event-system.php 19.1 prints none, T-S243-046); what
   was left is the body: every section a grey card on the grey page with a 4px gold shoulder, left aligned, the title navy.
   MEASURED LIVE (guide-for-members, guide-for-venues and guide-for-organisers, 1280 and 360): each guide is one .gs-guide-wrapper holding nine .gs-guide-section blocks, and
   ALL of their look is style="" attributes written by event_system_guide_section(): the section margin-bottom 24, padding 16, ground #f8f8f8, radius 8, border-left 4px #CC9900;
   the title h3 colour #031B83 and margin 0 0 8; every list margin 0 and padding-left 20. An inline style outranks every selector, so the properties that fight an inline value carry
   !important and nothing else does; that is the one way a stylesheet can restyle this markup, which the CHECK ruling for row 84 says to restyle as it stands.
   VALUES COPIED FROM THE SINGLE EVENT PAGE'S DESCRIPTION, nothing new: the sub-title is its h3 (event-page.css 5.9.7 with the page-polish.css article heading rule that reaches it:
   Montserrat 600, 20px on 1.3, 18px under 1024 and 17px under 601, gold, capitals, letter-spacing .04em, a 2px gold rule that hugs the words, 6px under the text); the text is
   .event-description's (15px on 1.65, navy, centred, 12px between paragraphs); the lists are its centred lists (a 6px gold dot before each item, 8px clear of it, 6px between items);
   the gold space between two sections is the host register's divider (event-page.css 11.12: 1px gold, 282px wide, centred, never wider than its box), with --sp-xl (24px) above and
   below it, the step the event description puts above each sub-title (5.9.7: margin var(--sp-xl) 0 var(--sp-md)); and each section is a column whose 12px (--sp-md) gap is the only space between its title and its text, as the cancel panel's rhythm (55). */
.gs-guide-wrapper { text-align: center; }
.gs-guide-wrapper .gs-guide-section {
    background: transparent !important;
    border-left: 0 !important;
    border-radius: 0 !important;
    padding: 0 !important;
    margin: 0 !important;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sp-md);
    position: relative;
    font-size: 15px;
    line-height: 1.65;
    color: var(--color-navy);
}
.gs-guide-wrapper .gs-guide-section + .gs-guide-section { margin-top: var(--sp-xl) !important; padding-top: var(--sp-xl) !important; }
.gs-guide-wrapper .gs-guide-section + .gs-guide-section::before {
    content: "";
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 282px;
    max-width: 100%;
    height: 1px;
    background: var(--color-gold);
}
.gs-guide-wrapper .gs-guide-section > h3 {
    display: table;
    margin: 0 auto !important;
    color: var(--color-gold) !important;
    font-family: var(--font-heading);
    font-size: 20px;
    font-weight: 600;
    line-height: 1.3;
    text-transform: uppercase;
    letter-spacing: .04em;
    padding-bottom: 6px;
    border-bottom: 2px solid var(--color-gold);
}
@media (max-width: 1023px) { .gs-guide-wrapper .gs-guide-section > h3 { font-size: 18px; } }
@media (max-width: 600px) { .gs-guide-wrapper .gs-guide-section > h3 { font-size: 17px; } }
.gs-guide-wrapper .gs-guide-section > div { width: 100%; }
.gs-guide-wrapper .gs-guide-section p { margin: 0 0 var(--sp-md); }
.gs-guide-wrapper .gs-guide-section ul { list-style: none; margin: 0 0 var(--sp-md) !important; padding-left: 0 !important; }
.gs-guide-wrapper .gs-guide-section p:last-child,
.gs-guide-wrapper .gs-guide-section ul:last-child { margin-bottom: 0 !important; }
.gs-guide-wrapper .gs-guide-section li { margin-bottom: 6px; padding-left: 0; }
.gs-guide-wrapper .gs-guide-section li:last-child { margin-bottom: 0; }
.gs-guide-wrapper .gs-guide-section li::before {
    content: "";
    display: inline-block;
    vertical-align: middle;
    width: 6px;
    height: 6px;
    margin-right: 8px;
    border-radius: 50%;
    background: var(--color-gold);
}
/* end of 11.14 */

/* end of 11 */

/* ============================================================================
   12. SECTION: Blog cards mobile polish
   ============================================================================ */

/* 12.1 Blog card — force title visible (Seeko entire-post-card hides it) */
/* 12.1.1 Entry header — positioned + visible */
article.post-card .entry-header {
    position: relative !important;
    height: auto !important;
    overflow: visible !important;
}
/* end of 12.1.1 */

/* 12.1.2 Entry title — typography + spacing */
article.post-card .entry-header .entry-title {
    display: block !important;
    font-family: 'Montserrat', sans-serif !important;
    font-weight: 700 !important;
    color: #031B83 !important;
    font-size: 16px !important;
    line-height: 1.3 !important;
    margin: 8px 0 !important;
    padding: 0 16px !important;
}
/* end of 12.1.2 */

/* 12.1.3 Entry title link — inherit colour */
article.post-card .entry-header .entry-title a {
    color: inherit !important;
    text-decoration: none !important;
}
/* end of 12.1.3 */
/* end of 12.1 */

/* 12.2 Collapse empty image area when no featured image */
article.post-card a.img-card-hover:empty {
    display: none !important;
}

/* 12.2.1 Collapse Seeko pseudo-element height spacers */
article.post-card .entry-wrapper::before,
article.post-card .entry-wrapper::after {
    height: 0 !important;
    display: none !important;
}

/* 12.2.2 Make entry-all flow normally instead of absolute overlay */
article.post-card .entry-all {
    position: relative !important;
    padding-bottom: 16px !important;
}

/* 12.2.3 Collapse entry-middle to content height */
article.post-card .entry-middle {
    height: auto !important;
    min-height: 0 !important;
}

/* 12.2.4 Entry content — show excerpt text */
article.post-card .entry-content {
    padding: 0 16px 12px !important;
    font-size: 14px;
    color: #333;
    line-height: 1.5;
}

/* 12.2.5 Entry wrapper — auto height */
article.post-card .entry-wrapper {
    height: auto !important;
}

/* 12.3 Category badge — brand-consistent */
article.post-card .meta-category .btn-tag {
    background: #031B83;
    color: #CC9900;
    border-color: #031B83;
    font-weight: 600;
}

/* 12.4 Mobile — full-width blog cards */
@media (max-width: 480px) {
    article.post-card {
        margin-left: 0 !important;
        margin-right: 0 !important;
    }
    /* Reduce excessive wrapper padding */
    .col-xl-3.col-lg-4.col-md-6 {
        padding-left: 5px !important;
        padding-right: 5px !important;
    }
}

/* ============================================================================
   13. SECTION: Character badge spacing on member cards
   ============================================================================ */

/* 13.1 T231: Character badges panel inside foreground card.
   S59 2026-04-15: bg dropped from #f5f5f5 to transparent so the whole foreground
   card reads as pure white (Rob 2026-04-15: "foreground card is still not white"). */
#buddypress #members-list .member-card-badges {
    background: transparent !important;
    border: 1px solid #CC9900 !important;
    border-radius: 10px !important;
    padding: 10px 12px !important;
    margin-top: 10px !important;
}

/* 13.2 T232: Badge pill spacing — increase gap for readability */
/* 13.2.1 Badges row container — flex wrap */
.member-card-character-badges {
    display: flex !important;
    flex-wrap: wrap !important;
    justify-content: center !important;
    gap: 8px !important;
    margin-top: 8px !important;
}
/* end of 13.2.1 */

/* 13.2.2 Character badge pill */
.member-character-badge {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    align-self: center !important;
    gap: 4px !important;
    padding: 4px 12px !important;
    border-radius: 12px !important;
    background: #fff !important;
    border: 1px solid #031B83 !important;
    font-size: 13px !important;
    line-height: 1 !important;
    white-space: nowrap !important;
}
/* end of 13.2.2 */

/* 13.2.3 Character badge emoji */
.character-badge-emoji {
    font-size: 14px !important;
    line-height: 1 !important;
    display: inline-flex !important;
    align-items: center !important;
}
/* end of 13.2.3 */

/* 13.2.4 Character badge label */
.character-badge-label {
    color: #031B83 !important;
    font-weight: 500 !important;
    line-height: 1 !important;
    display: inline-flex !important;
    align-items: center !important;
    /* S58-015: nudge label up 1px so visual text center (x-height midline)
       sits on the pill's geometric center line. Emoji glyph sits correctly
       at 0, so no emoji nudge needed. */
    position: relative !important;
    top: -1px !important;
}
/* end of 13.2.4 */
/* end of 13.2 */

/* 13.3 T291: Mobile badge pills uniform size */
@media (max-width: 480px) {
    .member-character-badge {
        padding: 3px 8px !important;
        font-size: 11px !important;
        min-width: 0 !important;
    }
    .character-badge-emoji {
        font-size: 12px !important;
    }
}

/* 13.4 Five member cards per row at widescreen (xl breakpoint and up).
        #members-list is a CSS grid with fixed-width tracks; override the
        grid-template-columns to widen each card from ~215px to ~262px.     */
@media (min-width: 1200px) {
    #buddypress #members-list,
    #buddypress div#members-dir-list ul#members-list {
        grid-template-columns: repeat(5, 1fr) !important;
    }
}

/* 13.5 Membership pill — canonical per-tier palette per BRAND_GUIDE.md §11 Membership
        Level Badges + S62 Rob sign-off of B23/B24/B25 (per-tier tint + matching text +
        no border) + D089 (Admin exception: solid green bg + navy text + navy border).
        Rewrite S63 Phase 1c — replaces the S58-015/S58-016 gold-family legacy palette
        that preceded the canonical sign-off.
        Targets the pill regardless of whether JS has floated it above the timestamp
        via .member-card-level-floated. */
/* 13.5.1 Membership pill — free tier */
/* D-652 25/09/2026, Rob: all tier pills cream and gold. Per-tier tint retired, replaced at
   source with the same three values as every other tier - see 42.7. */
#buddypress #members-list .member-card-level.level-free {
    background: var(--color-cream) !important;
    border: 1px solid var(--color-gold) !important;
    color: var(--color-navy) !important;
}
/* end of 13.5.1 */

/* 13.5.2 Membership pill — standard tier */
#buddypress #members-list .member-card-level.level-standard {
    background: var(--color-cream) !important;
    border: 1px solid var(--color-gold) !important;
    color: var(--color-navy) !important;
}
/* end of 13.5.2 */

/* 13.5.3 Membership pill — premium tier */
#buddypress #members-list .member-card-level.level-premium {
    background: var(--color-cream) !important;
    border: 1px solid var(--color-gold) !important;
    color: var(--color-navy) !important;
}
/* end of 13.5.3 */

/* 13.5.4 Membership pill — organiser tier */
#buddypress #members-list .member-card-level.level-organiser {
    background: var(--color-cream) !important;
    border: 1px solid var(--color-gold) !important;
    color: var(--color-navy) !important;
}
/* end of 13.5.4 */

/* 13.5.5 Membership pill — venue tier */
#buddypress #members-list .member-card-level.level-venue {
    background: var(--color-cream) !important;
    border: 1px solid var(--color-gold) !important;
    color: var(--color-navy) !important;
}
/* end of 13.5.5 */

/* 13.5.6 Membership pill — admin */
/* D-652 25/09/2026: retires the D089 solid-green exception. Rob's "EVERY tier pill... is the
   cream-and-gold pill" carries no admin carve-out, matching profile-editor.css .badge-admin. */
#buddypress #members-list .member-card-level.level-admin {
    background: var(--color-cream) !important;
    border: 1px solid var(--color-gold) !important;
    color: var(--color-navy) !important;
}
/* end of 13.5.6 */

/* 13.5.7 Membership pill — fallback (no .level-* class) */
/* Fallback for pills with no .level-* class (older rendering paths). */
#buddypress #members-list .member-card-level:not([class*="level-"]) {
    background: rgba(3, 27, 131, 0.06) !important;
    border: 0 none !important;
    color: #031B83 !important;
}
/* end of 13.5.7 */

/* 13.5.8 Membership pill — dating tier */
/* D-652 25/09/2026: was missing entirely (Rule 13). Added on the same recipe as every other
   tier here, see 42.7 .tier-badge--dating. */
#buddypress #members-list .member-card-level.level-dating {
    background: var(--color-cream) !important;
    border: 1px solid var(--color-gold) !important;
    color: var(--color-navy) !important;
}
/* end of 13.5.8 */
/* end of 13.5 */

/* 13.6 S58-017: Back to Members button — shown on no-results search pages.
        Injected by members_back_button_no_results() in functions.php §6.4. */
/* 13.6.1 Back-to-list container */
.members-back-to-list {
    text-align: center;
    margin: 24px 0;
}
/* end of 13.6.1 */

/* 13.6.2 Back button base */
.members-back-to-list .members-back-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 10px 24px;
    border-radius: 999px;
    background: #ffffff;
    border: 2px solid #CC9900;
    color: #031B83 !important;
    font-family: 'Montserrat', sans-serif;
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
    transition: background 0.2s ease;
}
/* end of 13.6.2 */

/* 13.6.3 Back button hover */
.members-back-to-list .members-back-button:hover {
    background: rgba(204, 153, 0, 0.1);
    color: #031B83 !important;
    text-decoration: none;
}
/* end of 13.6.3 */
/* end of 13.6 */
/* end of 13 */

/* ============================================================================
   14. SECTION: Account page styling fixes
   ============================================================================ */

/* 14.1 Account subscription badge — LB-023: cream bg + gold border + navy text
   (supersedes pre-LB-023 "blue bg → gold text" pattern) */
.account-badge {
    color: #031B83 !important;
    font-weight: 700 !important;
}

/* 14.2 Account status — "Active" should be green */
.account-status {
    color: var(--color-success) !important;
    font-weight: 600 !important;
}

/* 14.3 T236: Account details boxes — alignment, symmetry, email wrapping */
/* 14.3.1 Tab wrap — centred, max 600px */
.account-tab-wrap {
    text-align: center !important;
    max-width: 600px !important;
    margin: 0 auto !important;
}
/* end of 14.3.1 */

/* 14.3.2 Subscription + details boxes — gold border card */
.account-subscription-box,
.account-details-box {
    border-radius: 14px !important;
    padding: 28px 32px !important;
    border: 2px solid #CC9900 !important;
    background: #fff !important;
    box-shadow: 0 2px 8px rgba(3, 27, 131, 0.06) !important;
    margin-bottom: 24px !important;
}
/* end of 14.3.2 */

/* 14.3.3 Details table — full width */
.account-details-table {
    width: 100% !important;
    table-layout: auto !important;
}
/* end of 14.3.3 */

/* 14.3.4 Details table cells — padding + word-break */
.account-details-table td {
    padding: 10px 12px !important;
    vertical-align: middle !important;
    word-break: break-word !important;
    overflow-wrap: break-word !important;
}
/* end of 14.3.4 */

/* 14.3.5 Details label — fixed width */
.account-details-label {
    white-space: nowrap !important;
    width: 110px !important;
    text-align: left !important;
    color: #666 !important;
    font-size: 0.9rem !important;
}
/* end of 14.3.5 */

/* 14.3.6 Details value — left-aligned */
.account-details-value {
    text-align: left !important;
    word-break: break-all !important;
}
/* end of 14.3.6 */
/* end of 14.3 */

/* 14.4 Mobile account page */
@media (max-width: 480px) {
    .account-tab-wrap {
        max-width: 100% !important;
        padding: 0 8px !important;
    }
    .account-details-table td {
        display: block !important;
        width: 100% !important;
        padding: 4px 8px !important;
    }
    .account-details-label {
        font-weight: 600 !important; /* intentional: bolder label (600) when .account-details-table stacks to single column on mobile; base is theme-inherited 400 (Phase 2a S65) */
        /* color removed: duplicated base #666 at L1423 — Phase 2a S65 cascade cleanup */
        padding-bottom: 0 !important;
    }
}
/* end of 14 */

/* ============================================================================
   15. SECTION: Settings page centering + tab overflow fix
   ============================================================================ */

/* 15.1 T239: Settings sub-nav — scrollable, no overflow/truncation, no clipping */
/* 15.1.1 Subnav container — scroll x, padding */
#buddypress .item-list-tabs#subnav {
    overflow-x: auto !important;
    overflow-y: visible !important;
    -webkit-overflow-scrolling: touch;
    padding: 0 8px !important;
}
/* end of 15.1.1 */

/* 15.1.2 Subnav ul — flex no-wrap */
#buddypress .item-list-tabs#subnav ul {
    display: flex !important;
    flex-wrap: nowrap !important;
    white-space: nowrap !important;
    gap: 4px !important;
    justify-content: center !important;
    padding: 4px 8px !important;
    margin: 0 !important;
    list-style: none !important;
}
/* end of 15.1.2 */

/* 15.1.3 Subnav li — no shrink, visible overflow */
#buddypress .item-list-tabs#subnav ul li {
    flex-shrink: 0 !important;
    overflow: visible !important;
}
/* end of 15.1.3 */

/* 15.1.4 Subnav link — padding + no truncation */
#buddypress .item-list-tabs#subnav ul li a {
    padding: 6px 14px !important;
    font-size: 13px !important;
    white-space: nowrap !important;
    overflow: visible !important;
    text-overflow: unset !important;
}
/* end of 15.1.4 */
/* end of 15.1 */

/* 15.2 T238: Settings page content centering + input text centering */
/* 15.2.1 Standard form — centred max 700px */
#buddypress #item-body .standard-form {
    max-width: 700px !important;
    margin: 0 auto !important;
}
/* end of 15.2.1 */

/* 15.2.2 Form labels — block + centred */
#buddypress #item-body .standard-form label {
    text-align: center !important;
    display: block !important;
}
/* end of 15.2.2 */

/* 15.2.3 Form inputs — centred, max 500px */
#buddypress #item-body .standard-form input[type="text"],
#buddypress #item-body .standard-form input[type="email"],
#buddypress #item-body .standard-form input[type="password"],
#buddypress #item-body .standard-form textarea,
#buddypress #item-body .standard-form select {
    text-align: center !important;
    max-width: 500px !important;
    margin: 4px auto 16px !important;
    display: block !important;
}
/* end of 15.2.3 */
/* end of 15.2 */

/* 15.3 Email notification page — fix vertical Yes/No header alignment */
/* 15.3.0.1 Notifications table — fixed layout */
#buddypress .notification-settings {
    table-layout: fixed !important;
    width: 100% !important;
}
/* end of 15.3.0.1 */

/* 15.3.0.2 Notifications th — centred bottom */
#buddypress .notification-settings th {
    text-align: center !important;
    vertical-align: bottom !important;
    padding: 8px !important;
}
/* end of 15.3.0.2 */

/* 15.3.0.3 Title column — left aligned */
#buddypress .notification-settings th.title,
#buddypress .notification-settings td.title {
    text-align: left !important;
    width: auto !important;
}
/* end of 15.3.0.3 */

/* 15.3.0.4 Yes/No columns — fixed 40px */
#buddypress .notification-settings th.yes,
#buddypress .notification-settings th.no,
#buddypress .notification-settings td.yes,
#buddypress .notification-settings td.no {
    width: 40px !important;
    min-width: 40px !important;
    white-space: nowrap !important;
}
/* end of 15.3.0.4 */

/* 15.3.0.5 Icon column — hide */
#buddypress .notification-settings th.icon,
#buddypress .notification-settings td.icon {
    width: 0 !important;
    padding: 0 !important;
    display: none !important;
}
/* end of 15.3.0.5 */

/* 15.3.0.6 td — centred middle */
#buddypress .notification-settings td {
    text-align: center !important;
    vertical-align: middle !important;
    padding: 8px 4px !important;
}
/* end of 15.3.0.6 */

/* 15.3.0.7 First-child td — left aligned */
#buddypress .notification-settings td:first-child {
    text-align: left !important;
}
/* end of 15.3.0.7 */

/* 15.3.1 T241: Profile Visibility tab — centering and formatting */
/* 15.3.1.1 Profile-settings table — centred max 500px */
#buddypress .profile-settings {
    max-width: 500px !important;
    margin: 0 auto !important;
    border-collapse: separate !important;
    border-spacing: 0 8px !important;
}
/* end of 15.3.1.1 */

/* 15.3.1.2 Cells — centred Montserrat */
#buddypress .profile-settings th,
#buddypress .profile-settings td {
    text-align: center !important;
    padding: 8px 12px !important;
    font-family: 'Montserrat', sans-serif !important;
}
/* end of 15.3.1.2 */

/* 15.3.1.3 th — navy bold + gold border */
#buddypress .profile-settings th {
    color: #031B83 !important;
    font-weight: 700 !important;
    font-size: 14px !important;
    border-bottom: 2px solid #CC9900 !important;
}
/* end of 15.3.1.3 */

/* 15.3.1.4 Field-name td — left aligned navy */
#buddypress .profile-settings td.field-name {
    color: #031B83 !important;
    font-weight: 600 !important;
    font-size: 14px !important;
    text-align: left !important;
}
/* end of 15.3.1.4 */

/* 15.3.1.5 Select — gold border pill */
#buddypress .profile-settings select {
    border: 2px solid #CC9900 !important;
    border-radius: 8px !important;
    padding: 6px 12px !important;
    color: #031B83 !important;
    font-weight: 600 !important;
    background: #fff !important;
    text-align: center !important;
}
/* end of 15.3.1.5 */

/* 15.3.1.6 Submit row — centred */
#buddypress .profile-settings .submit {
    text-align: center !important;
}
/* end of 15.3.1.6 */
/* end of 15.3.1 */

/* 15.3.2 T242: Export Data tab — remove bullets, clean layout */
/* 15.3.2.1 Data form ul — no bullets, centred */
#buddypress .data-settings-form ul,
#buddypress form[action*="data"] ul {
    list-style: none !important;
    padding-left: 0 !important;
    margin: 16px auto !important;
    max-width: 400px !important;
    text-align: center !important;
}
/* end of 15.3.2.1 */

/* 15.3.2.2 Data form ul li — navy */
#buddypress .data-settings-form ul li,
#buddypress form[action*="data"] ul li {
    padding: 4px 0 !important;
    color: #031B83 !important;
    font-size: 14px !important;
    font-family: 'Montserrat', sans-serif !important;
}
/* end of 15.3.2.2 */

/* 15.3.2.3 Data form h2 — centred Montserrat */
#buddypress .data-settings-form h2,
#buddypress form[action*="data"] h2 {
    text-align: center !important;
    color: #031B83 !important;
    font-family: 'Montserrat', sans-serif !important;
}
/* end of 15.3.2.3 */
/* end of 15.3.2 */

/* 15.4 Mobile settings */
@media (max-width: 480px) {
    #buddypress .item-list-tabs#subnav ul li a {
        padding: 4px 8px !important;
        font-size: 12px !important;
    }
    #buddypress #item-body .standard-form {
        padding: 0 8px !important;
    }
}
/* end of 15 */

/* ============================================================================
   16. SECTION: Dashboard workspace content — universal centering
   All BP tab content inside the workspace must be centered and properly spaced.
   Covers: Reputation, Attendance, Wish List, Invites, Interests, Gallery, Suggestions
   ============================================================================ */

/* 16.1 (REMOVED S89) — Legacy `.col-inner > *:not(...)` text-align rule.
   Retired with the rest of the legacy `.col-inner`-grid layout. The new .app
   shell + section-card design handles its own text alignment per element. */

/* 16.1.1 Allow inner content blocks to left-align their text where appropriate.
   §68 My Interests redesign (2026-06-27): .mi-card removed from this rule —
   the redesigned cards are vertical and use text-align: center so its
   children (Sigil, name, since) stack and centre per the design spec. */
body.profile-dashboard-active .invite-tab-main,
body.profile-dashboard-active .attendance-profile-section table,
body.profile-dashboard-active .attendance-profile-section .attendance-event,
/* S224 15/09/26. The blanket `form` in this group was beating the export modal's own centring:
   the machine-readable control under the two buttons carries text-align: center from the file
   that emits it, and this !important overrode it, leaving the control 31.58px left of the box's
   centre at 1280 (600.92 against 632.50, measured by the code lane as cold_std22). Excluded here
   at SOURCE rather than answered with another !important beside it, which is the stacking Rob
   has ruled against: "lean, efficient code with no rule stacking, just one correct rule for
   things." Any other form that wants to centre itself can join the same exclusion. */
body.profile-dashboard-active form:not(.uksexp-form),
body.profile-dashboard-active .standard-form {
    text-align: left !important;
}

/* 16.2 Center headings on all workspace tab pages */
body.profile-dashboard-active #item-body h2,
body.profile-dashboard-active #item-body h3 {
    text-align: center !important;
    font-family: 'Montserrat', sans-serif !important;
}
/* S199 31/08/26, Rob: "only about me when you change body text colour, it doesn't change the
   colour of the name, only the 'joined' date on the customise page itself, but then when
   viewed on the public profile page, it has actually changed colour properly?"
   THE NAVY ABOVE WAS THE CAUSE, and it took CDP's own matched-rule list to see it: at
   `body.profile-dashboard-active #item-body h3` this is (1,1,2) with !important, which
   outranks the per-widget body-text override `.profile-widget[data-body-color] .widget-body *`
   at (0,2,0), also !important. `.bio-name` is an <h3>, so it kept the navy while `.bio-joined`
   (a span, untouched by this rule) obeyed the member's colour - exactly the split he saw. The
   public profile never carries `profile-dashboard-active`, which is why it was right there.
   The colour is PAGE chrome and has no business inside a widget's content, so it is excluded
   from widget bodies. The centring above is deliberately left alone. */
body.profile-dashboard-active #item-body h2:not(.widget-body *),
body.profile-dashboard-active #item-body h3:not(.widget-body *) {
    color: #031B83 !important;
}

/* 16.3 Center intro/description text */
body.profile-dashboard-active .mi-intro,
body.profile-dashboard-active .attendance-profile-section > p,
body.profile-dashboard-active .wishlist-intro {
    text-align: center !important;
    max-width: 600px !important;
    margin-left: auto !important;
    margin-right: auto !important;
}

/* 16.4 Center grids/card containers and flex containers within workspace */
body.profile-dashboard-active .mi-grid,
body.profile-dashboard-active .wishlist-grid {
    justify-content: center !important;
}

/* 16.4.1 Flex containers that need centering */
/* 16.4.1.1 Tab + wishlist tab content — justify centre */
body.profile-dashboard-active .item-list-tabs ul,
body.profile-dashboard-active .wishlist-tab-content {
    justify-content: center !important;
}
/* end of 16.4.1.1 */

/* 16.4.1.2 Attendance section — align-items centre */
/* Column flex containers need align-items for horizontal centering */
body.profile-dashboard-active .attendance-profile-section {
    align-items: center !important;
}
/* end of 16.4.1.2 */
/* end of 16.4.1 */

/* 16.4.2 Attendance stats boxes — center the row */
body.profile-dashboard-active .attendance-stats,
body.profile-dashboard-active .attendance-summary {
    display: flex !important;
    justify-content: center !important;
    flex-wrap: wrap !important;
    gap: 12px !important;
}

/* 16.4.3 Buttons inside workspace — center */
body.profile-dashboard-active .attendance-toggle-btn,
body.profile-dashboard-active .wishlist-empty-cta,
body.profile-dashboard-active .browse-more-link {
    display: block !important;
    margin-left: auto !important;
    margin-right: auto !important;
    text-align: center !important;
}

/* 16.5 Gallery title + count centering */
/* 16.5.1 Gallery title — centred */
body.profile-dashboard-active #rtmedia-gallery-container h2,
body.profile-dashboard-active .rtmedia-container h2,
body.profile-dashboard-active .gallery-title {
    text-align: center !important;
}
/* end of 16.5.1 */

/* 16.5.2 Gallery count — block centred */
body.profile-dashboard-active .rtmedia-item-count,
body.profile-dashboard-active .gallery-count {
    text-align: center !important;
    display: block !important;
}
/* end of 16.5.2 */
/* end of 16.5 */
/* end of 16 */
/* end of 12 */

/* ============================================================================
   17. SECTION: Preferences page fixes (T282, T308, T310, T322, T323)
   ============================================================================ */

/* 17.1 T282: Preferences page — all text centered */
/* 17.1.1 CTA text — centre */
body.profile-dashboard-active .cta-text {
    text-align: center !important;
}
/* end of 17.1.1 */

/* end of 17.1 */

/* 17.2 T308: Preferences workspace top-aligned with sidenav top */
body.profile-dashboard-active #buddypress #item-body {
    padding-top: 0 !important;
    margin-top: 0 !important;
}

/* 17.4 T322: CTA aligned tightly below banner, questions tight beneath.
   Progress bar must fill its grey wrap completely — no grey strip at top. */
/* 17.4.0.1 CTA-text margin reset */
body.profile-dashboard-active .cta-text {
    margin-top: 0 !important;
    margin-bottom: 6px !important;
}
/* end of 17.4.0.1 */

/* 17.4.0.2 Questionnaire progress bar — fill wrap */
body.profile-dashboard-active .questionnaire-progress .questionnaire-progress-bar,
body .questionnaire-progress .questionnaire-progress-bar {
    margin-top: 0 !important;
    margin-bottom: 0 !important;
    height: 100% !important;
}
/* end of 17.4.0.2 */

/* 17.4.1 [REMOVED X05, S238, 26/09/2026] This rule hid BuddyPress's default primary nav
   (#object-nav) and secondary nav (#subnav) on member pages, because the custom dashboard sidenav
   replaces them. They are no longer PRINTED (buddypress/legacy/members/single/home.php 1.3 and the
   child settings.php, plugins.php, profile.php and friends.php overrides), so there is nothing to
   hide, and a BP nav that ever returns now shows instead of hiding silently. Rob, 24/09/2026:
   nothing hidden, the only links are the ones attached to the buttons you can see. The Messages and
   Notifications subnav (17.4.6 below) is untouched. */

/* 17.4.6 T401 S59 2026-04-15: Messages + Notifications BP subnav restyle.
   Brand-aligned horizontal pill bar: cream cards with gold border, navy text,
   active state inverts to gold-on-navy. Replaces BP legacy grey tabs. */
/* 17.4.6.1 Subnav container — block layout, no padding/border */
body.messages #buddypress #subnav.item-list-tabs,
body.notifications #buddypress #subnav.item-list-tabs {
    display: block !important;
    height: auto !important;
    margin: 0 0 18px 0 !important;
    padding: 0 !important;
    background: transparent !important;
    border: none !important;
}
/* end of 17.4.6.1 */
/* 17.4.6.2 Subnav UL — flex row, 10px gap */
body.messages #buddypress #subnav.item-list-tabs ul,
body.notifications #buddypress #subnav.item-list-tabs ul {
    display: flex !important;
    flex-wrap: wrap !important;
    gap: 10px !important;
    list-style: none !important;
    margin: 0 !important;
    padding: 0 !important;
    background: transparent !important;
    border: none !important;
}
/* end of 17.4.6.2 */
/* 17.4.6.3 Subnav LI — reset background/border/list-style */
body.messages #buddypress #subnav.item-list-tabs li,
body.notifications #buddypress #subnav.item-list-tabs li {
    margin: 0 !important;
    padding: 0 !important;
    background: transparent !important;
    border: none !important;
    list-style: none !important;
}
/* end of 17.4.6.3 */
/* 17.4.6.4 Subnav LI A — pill base (cream bg, gold border, navy text, 38px) */
body.messages #buddypress #subnav.item-list-tabs li a,
body.notifications #buddypress #subnav.item-list-tabs li a {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    align-self: center !important;
    height: 38px !important;
    padding: 0 18px !important;
    border-radius: 9999px !important; /* S68 F3 — pill shape per LB-023/D090 */
    background: #fffbe6 !important;
    border: 2px solid #CC9900 !important;
    color: #031B83 !important;
    font-family: 'Montserrat', sans-serif !important; /* S68 F3 — BRAND_GUIDE §3 font */
    font-weight: 600 !important;
    font-size: 13px !important;
    text-decoration: none !important;
    box-shadow: 0 2px 6px rgba(0,0,0,0.10) !important;
    transition: all 0.18s ease !important;
}
/* end of 17.4.6.4 */
/* 17.4.6.5 Subnav LI A hover — gold bg invert */
body.messages #buddypress #subnav.item-list-tabs li a:hover,
body.notifications #buddypress #subnav.item-list-tabs li a:hover {
    background: #CC9900 !important;
    border-color: #031B83 !important;
    color: #031B83 !important;
    box-shadow: 0 4px 10px rgba(0,0,0,0.18) !important;
}
/* end of 17.4.6.5 */
/* 17.4.6.6 Subnav LI.current/selected A — navy bg + gold text active */
body.messages #buddypress #subnav.item-list-tabs li.current a,
body.messages #buddypress #subnav.item-list-tabs li.selected a,
body.notifications #buddypress #subnav.item-list-tabs li.current a,
body.notifications #buddypress #subnav.item-list-tabs li.selected a {
    background: #031B83 !important;
    border-color: #031B83 !important;
    color: #CC9900 !important;
}
/* end of 17.4.6.6 */
/* 17.4.6.7 Subnav LI A SPAN — count badge (gold pill) */
body.messages #buddypress #subnav.item-list-tabs li a span,
body.notifications #buddypress #subnav.item-list-tabs li a span {
    display: inline-block !important;
    margin-left: 6px !important;
    padding: 1px 7px !important;
    background: #CC9900 !important;
    color: #031B83 !important;
    border-radius: 9999px !important;
    font-size: 11px !important;
    font-weight: 700 !important;
    line-height: 1.4 !important;
}
/* end of 17.4.6.7 */
/* 17.4.6.8 Subnav LI.current A SPAN — current state count badge */
body.messages #buddypress #subnav.item-list-tabs li.current a span,
body.notifications #buddypress #subnav.item-list-tabs li.current a span {
    background: #CC9900 !important;
    color: #031B83 !important;
}
/* end of 17.4.6.8 */
/* end of 17.4.6 */

/* 17.4.2 Let .cta-banner position absolute inside .col-inner so it doesn't
   consume a grid row and push questionnaire content down. */
/* 17.4.2.1 Col-inner relative positioning */
body.bp-user .col-inner { position: relative !important; }
/* end of 17.4.2.1 */

/* 17.4.2.2 Questionnaire wrapper — zero top margin/padding */
body.bp-user .questionnaire-wrapper { padding-top: 0 !important; margin-top: 0 !important; }
/* end of 17.4.2.2 */
/* end of 17.4.2 */

/* 17.4.3 CTA banner click pass-through: the .cta-banner is absolute-positioned
   and its box can overlap interactive elements below (sliders, skip/next buttons).
   Disable pointer-events on the banner box itself, then re-enable pointer-events
   only on the text children so the back-to-summary link still works. */
/* 17.4.3.1 CTA banner — pointer-events none */
.cta-banner {
    pointer-events: none !important;
}
/* end of 17.4.3.1 */

/* 17.4.3.2 CTA banner children — re-enable pointer-events */
.cta-banner .cta-text,
.cta-banner a,
.cta-banner .cta-back-link {
    pointer-events: auto !important;
}
/* end of 17.4.3.2 */
/* end of 17.4.3 */

/* 17.4.4 Back-to-summary link: looks like plain styled text, underlines on hover
   to make clickability obvious (not styled as a button). */
/* 17.4.4.1 Back link base */
.cta-back-link {
    color: #CC9900 !important;
    font-weight: 600 !important;
    text-decoration: none !important;
    cursor: pointer !important;
    pointer-events: auto !important;
    transition: text-decoration-color 120ms ease, color 120ms ease;
}
/* end of 17.4.4.1 */

/* 17.4.4.2 Back link hover/focus */
.cta-back-link:hover,
.cta-back-link:focus {
    text-decoration: underline !important;
    text-underline-offset: 2px !important;
    color: #b88500 !important;
}
/* end of 17.4.4.2 */
/* end of 17.4.4 */

/* 17.5 T323: Photo panel header — corner label + equal padding */
/* 17.5.1 Photo panel handle — base padding */
.photo-panel-handle {
    padding: 6px 10px !important;
    min-height: auto !important;
}
/* end of 17.5.1 */

/* 17.5.2 Corner label — an ordinary in-flow header title */
/* S199 31/08/26, Rob: this rule dated from when the photo panel's header was a small tab
   floating over the top-left of the photo, so the label was pinned absolutely and painted
   white to read against the image. S198 put the header back in normal flow as an ordinary
   widget bar, and this rule was left behind: `position: absolute` took the label OUT of the
   flex flow, so it reserved no width, and the three controls packed against the LEFT edge
   instead of the right corner, sitting on top of the word PHOTO. It is the same slot the
   standard header gives `.widget-title`, so it gets the same treatment. */
.photo-corner-label {
    position: static !important;
    top: auto !important;
    left: auto !important;
    flex: 1 1 auto !important;
    font-size: 10px !important;
    font-weight: 700 !important;
    letter-spacing: 1px !important;
    text-transform: uppercase !important;
    color: #031B83 !important;
    pointer-events: none !important;
}
/* end of 17.5.2 */

/* 17.5.3 Photo panel handle — relative + symmetric padding */
.photo-panel-handle {
    position: relative !important;
    padding-top: 6px !important;
    padding-bottom: 6px !important;
}
/* end of 17.5.3 */
/* end of 17.5 */
/* end of 17 */

/* ============================================================================
   18. SECTION: Site-wide button brand override (T266, T270, T271, T272, T273, T295)
   ============================================================================ */

/* 18.1 T266: ALL generic BuddyPress buttons → white bg + gold border pill
   Targets: generic-button links, BP submit buttons, BP action buttons, message buttons.
   Excludes: interest-btn (has own styles in interest-system.php), header btns (style.css),
   hide-att-btn (inline in event-system.php, overridden below in 18.3). */
/* 18.1.0.1 Generic BP buttons — base style
   S86-009: removed `body.profile-dashboard-active button.btn` and
   `body.profile-dashboard-active .button` from this legacy site-wide brand
   override. The new design system in §42 (S86-003) introduces its own .btn
   family (.btn--primary / .btn--ghost / .btn--danger / .btn--subtle /
   .btn--icon) that handles its own styling per-variant. The legacy override's
   !important rules were beating the new variant rules at specificity (0,2,2)
   and producing the wrong visual hierarchy on the new /account/ page (Cancel
   button looking primary, Change plan looking subtle). Generic non-.btn BP
   submit/action buttons still get the brand override here. */
/* S100 26/05/26: added `:not()` exclusions so the legacy BP-button override
   YIELDS to any button that has been swept to the new universal class system
   (.btn-option / .btn-dashboard / .btn-menu). Buttons not yet swept continue
   to receive the old cream+gold treatment until their page sweep lands. */
/* S198 29/08/26: `.member-fav-btn` added to the same exclusion list. It is not an
   unswept legacy button - it is a fully designed one (cream fill, gold border, gold
   + circle, D-084 / D-275, styled in uksocials-member-favourites.php) - but because
   it carries none of the universal classes this rule was overriding its radius and
   type at (1,5,1) and it alone rendered off-shape in the profile action row. Rob:
   "the three buttons above should all be the exact same shape and size and uniform".
   Exempting it here is the mechanism this rule already provides, rather than stacking
   a higher-specificity override on top of it. */
/* S244 row 128: #members_search_submit (the Members search box's magnifying-glass button, class btn-primary, so it matched this rule) is exempted
   the same way, by :where(:not(#members_search_submit)) on the button[type="submit"] alternative of this rule and of 18.1.0.2 below: :where() adds no
   specificity, so no other button's cascade moves. It had been fought with a pile of !important rules at 25.2.7 to 25.2.9 (white fill, 2px gold ring and
   22px radius from here, navy fill and gold label on hover); with the exemption those rules own the button outright and need no !important. */
#buddypress .generic-button a:not(.btn-option):not(.btn-dashboard):not(.btn-menu):not(.btn):not(.member-fav-btn),
#buddypress input[type="submit"]:not(.btn-option):not(.btn-dashboard):not(.btn-menu):not(.btn),
#buddypress button[type="submit"]:not(.btn-option):not(.btn-dashboard):not(.btn-menu):not(.btn):where(:not(#members_search_submit)),
#buddypress .button-nav a:not(.btn-option):not(.btn-dashboard):not(.btn-menu):not(.btn),
#buddypress .acomment-reply a:not(.btn-option):not(.btn-dashboard):not(.btn-menu):not(.btn),
#buddypress #message-threads .action a:not(.btn-option):not(.btn-dashboard):not(.btn-menu):not(.btn),
body.profile-dashboard-active input[type="submit"]:not(.btn-option):not(.btn-dashboard):not(.btn-menu):not(.btn),
body.profile-dashboard-active .generic-button a:not(.btn-option):not(.btn-dashboard):not(.btn-menu):not(.btn):not(.member-fav-btn) {
    background: #fff !important;
    border: 2px solid #CC9900 !important;
    color: #031B83 !important;
    border-radius: 22px !important;
    font-family: 'Montserrat', sans-serif !important;
    font-weight: 600 !important;
    font-size: 13px !important;
    padding: 8px 20px !important;
    text-transform: uppercase !important;
    letter-spacing: 0.4px !important;
    cursor: pointer !important;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease !important;
    text-decoration: none !important;
    display: inline-block !important;
    line-height: 1.4 !important;
    box-shadow: none !important;
}
/* end of 18.1.0.1 */

/* 18.1.0.2 Generic BP buttons — hover invert (S100: same yield-to-new-class exclusions) */
#buddypress .generic-button a:not(.btn-option):not(.btn-dashboard):not(.btn-menu):not(.btn):not(.member-fav-btn):hover,
#buddypress input[type="submit"]:not(.btn-option):not(.btn-dashboard):not(.btn-menu):not(.btn):hover,
#buddypress button[type="submit"]:not(.btn-option):not(.btn-dashboard):not(.btn-menu):not(.btn):where(:not(#members_search_submit)):hover,
#buddypress .button-nav a:not(.btn-option):not(.btn-dashboard):not(.btn-menu):not(.btn):hover,
#buddypress .acomment-reply a:not(.btn-option):not(.btn-dashboard):not(.btn-menu):not(.btn):hover,
#buddypress #message-threads .action a:not(.btn-option):not(.btn-dashboard):not(.btn-menu):not(.btn):hover,
body.profile-dashboard-active input[type="submit"]:not(.btn-option):not(.btn-dashboard):not(.btn-menu):not(.btn):hover,
body.profile-dashboard-active .generic-button a:not(.btn-option):not(.btn-dashboard):not(.btn-menu):not(.btn):not(.member-fav-btn):hover {
    background: #031B83 !important;
    color: #CC9900 !important;
    border-color: #031B83 !important;
}
/* end of 18.1.0.2 */

/* 18.1.1 Preserve interest-btn specific styles — do NOT override */
#buddypress .generic-button a.interest-btn,
#buddypress .generic-button a.interest-btn-active,
#buddypress .generic-button a.interest-btn-matched,
.generic-button a.interest-btn,
.generic-button a.interest-btn-active,
.generic-button a.interest-btn-matched {
    font-size: 12px !important;
}

/* 18.1.2 THE PROFILE ACTION ROW'S TWO BUTTONS HUG THEIR LABEL (S224 14/09/26)
   Rob, note 97: "these buttons are too wide, so give them fifteen pixel padding and make sure
   they're still centered", and note 38 on the same pair: "way too wide. Apply the 15 pixel
   padding on either end of both".
   MEASURED BEFORE on cold_ven30's profile at 1280: each wrap 146.00px and each button filling
   it, so the word Favourite (54.02px) floated with 45.98 and 46.00 either side.
   THE CAUSE IS THE PARENT THEME, not our CSS: buddypress.min.css carries
   #item-buttons .generic-button:not(.friendship-button) a { width: 100% }, so the button takes
   the whole column whatever padding it is given. Section 18 exists to override exactly those
   BuddyPress rules, which is why this sits here rather than as a new section of its own.
   The wraps shrink with the buttons so the row's own justify-content: center still centres
   the pair. */
#buddypress .profile-header-actions .generic-button,
.profile-header-actions .generic-button {
    width: auto !important;
    min-width: 0 !important;
}
#buddypress .profile-header-actions .generic-button a,
.profile-header-actions .generic-button a {
    width: auto !important;
    min-width: 0 !important;
    padding-left: 15px !important;
    padding-right: 15px !important;
}
/* end of 18.1.2 */

/* 18.2 T271: Send Suggestion button → white bg + gold border */
/* 18.2.1 Suggestion submit — base */
.suggestions-submit {
    background: #fff !important;
    border: 2px solid #CC9900 !important;
    color: #031B83 !important;
    border-radius: 22px !important;
    padding: 10px 28px !important;
    font-family: 'Montserrat', sans-serif !important;
    font-weight: 600 !important;
    font-size: 14px !important;
    text-transform: uppercase !important;
    letter-spacing: 0.4px !important;
}
/* end of 18.2.1 */

/* 18.2.2 Suggestion submit hover */
.suggestions-submit:hover {
    background: #031B83 !important;
    color: #CC9900 !important;
    border-color: #031B83 !important;
    transform: scale(1.03);
}
/* end of 18.2.2 */
/* end of 18.2 */

/* 18.3 T270: Attendance Hide button → white bg + gold border (override inline styles) */
/* 18.3.1 Hide button base */
.hide-att-btn {
    background: #fff !important;
    border: 2px solid #CC9900 !important;
    color: #031B83 !important;
}
/* end of 18.3.1 */

/* 18.3.2 Hide button hover */
.hide-att-btn:hover {
    background: #031B83 !important;
    color: #CC9900 !important;
    border-color: #031B83 !important;
}
/* end of 18.3.2 */

/* 18.3.3 Hide button pressed state */
.hide-att-btn[aria-pressed="true"] {
    background: #031B83 !important;
    color: #CC9900 !important;
    border-color: #031B83 !important;
}
/* end of 18.3.3 */

/* 18.3.4 Hide button pressed hover */
.hide-att-btn[aria-pressed="true"]:hover {
    background: #fff !important;
    color: #031B83 !important;
    border-color: #CC9900 !important;
}
/* end of 18.3.4 */
/* end of 18.3 */

/* 18.4 S58 2026-04-14: Rogue .header-logout-btn block removed. Unified sizing
   for LOGOUT + DASHBOARD now lives in style.css so both buttons stay visually
   identical. Do not re-add a .header-logout-btn-only rule here. */

/* 18.6 T295: Attendance count badge on member cards */
/* 18.6.1 Attendance badge base */
#buddypress #members-list .member-attendance-badge {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    align-self: center !important;
    /* S133 D-260: gap 4->3 and padding 12->8 to stay IDENTICAL to the age +
       postcode pills (§26.6.1), which were tightened when the age badge joined
       the row inside a 118px .item. Rob's T406 rule is that these badges are
       "the same size and style" - so all three move together or none do. */
    gap: 3px;
    background: #fff;
    border: 1px solid #CC9900;
    border-radius: 12px;
    padding: 4px 8px !important;
    font-family: 'Montserrat', sans-serif;
    font-size: 11px;
    font-weight: 600;
    color: #031B83;
    line-height: 1 !important;
    margin-top: 10px !important;
}
/* end of 18.6.1 */

/* 18.6.2 Attendance badge icon */
#buddypress #members-list .member-attendance-badge .att-icon {
    font-size: 13px;
    line-height: 1 !important;
    display: inline-flex !important;
    align-items: center !important;
}
/* end of 18.6.2 */

/* 18.6.3 Attendance badge — hidden state (red) */
/* T295: Red flag for hidden attendance */
#buddypress #members-list .member-attendance-badge.att-hidden {
    border-color: #cc3333;
    color: #cc3333;
    background: #fff5f5;
}
/* end of 18.6.3 */
/* end of 18.6 */
/* end of 18 */

/* ============================================================================
   19. SECTION: Remaining visual fixes (T296, T334, T343)
   ============================================================================ */

/* 19.1 T296: Reputation page text centering */
/* 19.1.1 Reputation containers — text centre */
body.profile-dashboard-active .widget-reputation,
body.profile-dashboard-active .reputation-badges,
body.profile-dashboard-active .reputation-empty {
    text-align: center !important;
}
/* end of 19.1.1 */

/* 19.1.2 Individual reputation badge — text centre */
body.profile-dashboard-active .reputation-badges .reputation-badge {
    text-align: center !important;
}
/* end of 19.1.2 */
/* end of 19.1 */

/* 19.2 T343: Teapot emoji fallback — use a universally-supported emoji */
.event-card .teapot-fallback {
    font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', sans-serif !important;
}
/* end of 19 */

/* ============================================================================
   20. SECTION: Top Bar Social Icons — True Centre
   S58 WS-walkthrough fix. Top bar is a 3-column Elementor flex with
   space-between, but the left and right widgets are different widths, so the
   middle social-icon column lands ~48px left of true centre. Anchor the
   widget absolutely to the full-width row so it sits on viewport centre.
   ============================================================================ */

/* 20.1 Make the full-width top row positioned so we can anchor the social widget */
.uksp-element-79b2e73 {
    position: relative !important;
}

/* 20.1.1 REMOVED — email widget is now hidden globally via style.css §5.4. */

/* 20.2 Pull the social-icons widget out of flex flow and centre on the row */
.uksp-element-c38eb63 {
    position: absolute !important;
    left: 50% !important;
    top: 50% !important;
    transform: translate(-50%, -50%) !important;
    z-index: 5 !important;
}
/* end of 20 */

/* ============================================================================
   21. SECTION: Dashboard — RETIRED.
   Old hand-rolled dashboard CSS removed S103 2026-06-05. Replaced by the
   Dashboard design-agent port — see §43 below for the verbatim port from
   uksocials-club/project/dashboard.css.
   ============================================================================ */
/* end of 21 */

/* ============================================================================
   22. SECTION: Sidenav badge (notification/message counts)
   The badge is a fixed-size gold circle containing a count. Pure geometric
   centring with line-height locked to box height and tabular-nums for
   consistent digit widths. Verified against 1/5/9/10/16/22/100 in DevTools.
   ============================================================================ */

/* 22.1 Badge — pure geometric centring + approved small-pill colours
   (light gold bg + darker gold bottom edge, dark blue numerals for readability). */
.sidenav-badge {
    padding: 0 !important;
    line-height: 21px !important;
    font-size: 11px !important;
    width: 21px !important;
    height: 21px !important;
    box-sizing: border-box !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    font-variant-numeric: tabular-nums !important;
    text-align: center !important;
    background: var(--color-cream) !important; /* S207 05/09/26: was a non-brand cream. BRAND_GUIDE (LOCKED) makes #FFFBE6 the one brand cream, #FFF5CC hover only. */ /* The S58 note here said Rob preferred a darker cream for badges; superseded by D-181's green tick, so this rule paints nothing today. */
    color: #031B83 !important;
    border: 1px solid #CC9900 !important;
    border-bottom-width: 2px !important;
    font-weight: 700 !important;
    box-shadow: none !important;
}
/* end of 22 */

/* ============================================================================
   23. SECTION: Dashboard feed rows — RETIRED.
   Replaced S103 2026-06-05 by Dashboard design-agent port — see §43 below.
   ============================================================================ */
/* end of 23 */

/* ============================================================================
   24. SECTION: Dashboard standard button overrides — RETIRED.
   Replaced S103 2026-06-05 by Dashboard design-agent port — see §43 below.
   ============================================================================ */
/* end of 24 */

/* ============================================================================
   25. SECTION: Members directory — on-brand the grey bits
   AMENDMENT S58 2026-04-14: pag-count, dir-search input, order-by label + select
   get navy text + gold border/hover per brand. No more greys.
   ============================================================================ */
/* 25.1 Pagination count ("Viewing 1 - 22 of 22 members") */
#buddypress .pag-count,
#buddypress #member-dir-count-top,
#buddypress #member-dir-count-bottom {
    color: #031B83 !important;
    font-family: 'Nunito Sans', sans-serif !important;
    font-weight: 600 !important;
}
/* 25.1.1 Centre the bottom pagination count under the gallery (S59 2026-04-15). */
body.directory.members #buddypress #pag-bottom,
body.directory.members #buddypress #member-dir-count-bottom {
    text-align: center !important;
    width: 100% !important;
    display: block !important;
}

/* 25.1.2 Members directory page numbers: the site's own pagination (S245 row 80, Rob 07/10/26: "on the members page beneath the member
   carousel, you'll see that the pagination isn't the correct pagination. it looks slightly off when you hover the page number, it doesn't
   highlight properly and the arrows should be gold. I think in this one you can see that it's on page two. I don't think the background of
   that number two box is white either. So yeah the whole pagination thing here has to be looked at.").
   MEASURED LIVE, the real cascade at 1280 and 360 (BuddyPress's own markup, a prev link, number links, a span.current and a next link, placed
   in #member-dir-pag-bottom in the browser, nothing saved; no test account sees more than one page): nothing of ours styled it (the only rule of ours that reached
   it was the site-wide a:hover text-decoration). Every rule that styled .page-numbers was the parent theme's (theme-static.min.css and seeko-dynamic.css): the numbers rgb(51,51,51) grey; on hover a grey ring
   rgb(218,218,218), grey text rgb(128,128,128) and a grey shadow, which never read as the site's highlight; the current page a transparent box with a
   60 per cent gold ring, so the page's own tinted ground showed through it (Rob's "not white"); both arrows the same grey; and the whole row pushed to the
   right edge (.pagination-links { justify-content: flex-end }) under the count line that 25.1.1 centres.
   WHAT IT NOW IS, COPIED AND NOT DESIGNED: the dashboard's own page buttons, .workspace .att-pagination__btn (18.x, signed off and used on Attendance, Wish
   List, Events, Suggestions and My Interests) and its .att-pagination row. The circle (36px, 1.5px gold ring, cream fill, navy, the one gold shadow
   --shadow-gold-hover, the 150ms transition), its hover (scale 1.08, the cream unchanged), its pressed state (cream-hover, no shadow) and the row (centred, 16px gap) are
   those rules' values. The digits take .att-pagination__info's face (Montserrat 700, navy) at 14px. The two things Rob named that the dashboard buttons do not carry: the
   arrows are gold (var(--color-gold)) and the current page is white (var(--color-surface)) and flat
   (no shadow, no pointer), so it reads as "you are here" beside the cream links. flex-wrap keeps a long run of pages (1 ... 11 12 ... 120) inside a 360 screen.
   THE DIGITS ARE 14px, NOT THE 13px OF .att-pagination__info. 14px is the size of the chevron the dashboard buttons draw, and it is the one size at which the digit centres
   exactly. Measured on the painted digits at 8 device pixels to the CSS pixel, with the row moved to four fractional positions down the page (0, .25, .5, .75), at 1280 and at
   360: at 13px a digit painted +0.31 below the ring's centre or -0.69 above it depending only on the row's fractional position, because Chrome rounds the ring and the text
   to the pixel grid separately and 13px puts the text on a half pixel, so half of all positions broke the half-pixel centring rule; at 14px it painted 0.00 at every
   one of them (measurements/p80_phase).
   THE ARROWS ARE THE DASHBOARD'S OWN CHEVRONS, NOT TEXT ARROWS. BuddyPress prints a text arrow (the left and right arrow characters), which Montserrat does not carry, so each machine draws it
   from whichever symbol font it has; here it painted 1.0px BELOW the ring's centre (read from the circle's own pixels at dpr 8, the gold arrow scanned apart from its gold ring) and
   would sit elsewhere on a Mac or a phone. The text is hidden (font-size 0, still there for a screen reader) and the same 14px chevron the dashboard buttons draw (the SVG paths of
   invite-system.php 3066 and 3068, stroke 2.5, round caps) is painted in the link's own gold from a mask, centred by the circle's flex box like every other glyph on the site's buttons.
   The ids in the selector are what beat the theme's (0,4,0) hover and focus rules without !important. */
body.directory.members #buddypress .pagination-links {
    justify-content: center;
    flex-wrap: wrap;
    gap: var(--sp-lg);
}
body.directory.members #buddypress .pagination-links .page-numbers {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    min-width: 36px;
    height: 36px;
    padding: 0 8px;
    margin: 0;
    border-radius: 9999px;
    border: 1.5px solid var(--color-gold);
    background: var(--color-cream);
    color: var(--color-navy);
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 14px;
    line-height: 1;
    text-decoration: none;
    box-shadow: var(--shadow-gold-hover);
    cursor: pointer;
    transition: background var(--duration-fast) var(--ease-out),
                transform var(--duration-fast) var(--ease-out);
}
body.directory.members #buddypress .pagination-links a.page-numbers:hover { background: var(--color-cream); transform: scale(1.08); }
body.directory.members #buddypress .pagination-links a.page-numbers:active { background: var(--color-cream-hover); box-shadow: none; }
body.directory.members #buddypress .pagination-links .page-numbers.current { background: var(--color-surface); box-shadow: none; cursor: default; }
body.directory.members #buddypress .pagination-links .page-numbers.prev,
body.directory.members #buddypress .pagination-links .page-numbers.next { color: var(--color-gold); font-size: 0; }
body.directory.members #buddypress .pagination-links .page-numbers.prev::before,
body.directory.members #buddypress .pagination-links .page-numbers.next::before {
    content: "";
    width: 14px;
    height: 14px;
    background-color: currentColor;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
    -webkit-mask-size: 14px 14px;
    mask-size: 14px 14px;
}
body.directory.members #buddypress .pagination-links .page-numbers.prev::before { -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 18l-6-6 6-6'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 18l-6-6 6-6'/%3E%3C/svg%3E"); }
body.directory.members #buddypress .pagination-links .page-numbers.next::before { -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 18l6-6-6-6'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 18l6-6-6-6'/%3E%3C/svg%3E"); }
body.directory.members #buddypress .pagination-links .page-numbers.dots { border: 0; background: transparent; box-shadow: none; min-width: 0; padding: 0; cursor: default; }
/* end of 25.1.2 */

/* 25.2 Search form row — input with embedded magnifier button on the right.
   <!-- AMENDMENT S59 2026-04-15 rev5: button moved from external flex item to
   absolute-positioned overlay inside the input's right edge. Input gets
   padding-right to reserve the icon area. form has position:relative so the
   absolute button anchors to it. --> */
/* 25.2.0 Members directory intro line: sits under the "Members" page title.
   Injected by members_directory_subtitle() (functions.php §6.6b). Spacing is a
   uniform 20px above and below the line so the header reads symmetrical (the
   search bar previously sat flush against it). Per Rob 26/06/26. */
.members-directory-subtitle {
    text-align: center;
    max-width: 620px;
    margin: 20px auto 20px;
    color: var(--color-navy, #031B83);
    font-family: var(--font-body, 'Nunito Sans', sans-serif);
    font-size: 16px;
    line-height: 1.45;
    font-weight: 400;
}
/* Match the gap ABOVE the intro line to the gap below it (20px) so spacing is
   uniform. Scoped via :has() to the members directory only (where the line
   exists), so other pages' page-header spacing is untouched. */
.svq-page-header:has(.members-directory-subtitle) .entry-title {
    margin-bottom: 20px !important;
}
/* end of 25.2.0 */

/* 25.2.1 Dir-search containers — full width */
#buddypress #members-dir-search,
#buddypress .dir-search {
    width: 100% !important;
}
/* end of 25.2.1 */

/* 25.2.2 Search form — 90% gallery width + relative */
/* Search form = 90% of gallery window width at every viewport.
   Gallery window = parent width - (2 × arrow padding).
   calc() mirrors the gallery-wrap padding per breakpoint. */
#buddypress #search-members-form {
    display: block !important;
    /* Per Rob 26/06/26: halved (0.9 -> 0.45) so the search bar is ~50% of its
       previous width. Still centred via margin auto.
       S220 14/09/2026, Rob: "The search box doesn't need to be so wide either.
       Reduce it by like twenty percent." 0.45 x 0.8 = 0.36, so the measured
       422.09px at 1280 becomes 337.67px. Changed at source rather than fought
       with a second rule further down the file. */
    width: calc((100% - 112px) * 0.36) !important;
    max-width: calc((1400px - 112px) * 0.36) !important;
    margin: 0 auto !important;
    position: relative !important;
    padding: 0 !important;
    box-sizing: border-box !important;
}
/* end of 25.2.2 */

/* 25.2.3 Search form @<=768px width */
@media (max-width: 768px) {
    #buddypress #search-members-form {
        width: calc((100% - 80px) * 0.9) !important;
    }
}
/* end of 25.2.3 */

/* 25.2.4 Search form @<=480px width */
@media (max-width: 480px) {
    #buddypress #search-members-form {
        width: calc((100% - 64px) * 0.9) !important;
    }
}
/* end of 25.2.4 */

/* 25.2.5 Search label — hide */
#buddypress #search-members-form label[for="members_search"] {
    display: none !important;
}
/* end of 25.2.5 */

/* 25.2.6 Search input base style */
#buddypress #members-dir-search input[type="search"],
#buddypress #members-dir-search input[type="text"],
#buddypress .dir-search input[type="search"],
#buddypress .dir-search input[type="text"],
#buddypress #members_search {
    display: block !important;
    width: 100% !important;
    background: #ffffff !important;
    border: 2px solid #CC9900 !important;
    border-radius: 8px !important;
    color: #031B83 !important;
    font-family: 'Nunito Sans', sans-serif !important;
    font-weight: 500 !important;
    font-size: 14px !important;
    /* right padding reserves space for the absolute-positioned magnifier icon; S219 (Rob 10/09/26,
       all normal text centred): the left side matches it so the text sits in the true middle */
    padding: 0 48px !important;
    text-align: center !important;
    height: 40px !important;
    box-sizing: border-box !important;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12) !important;
    transition: all 0.18s ease !important;
}
/* end of 25.2.6 */

/* 25.2.7 Search submit button — absolute icon */
/* Search submit button: absolute inside the input's right edge, transparent background, just the icon visible. right offset = form's right padding (91px) + 6px so the icon sits 6px inside the input's gold border.
   S244 row 128 (Rob 08/10 ~19:1x, on hovering it: "it goes a weird colour and doesn't have the the vertical border in gold to the left hand side of it. That's wrong."):
   this block and 25.2.8 below are replaced, and none of it is !important any more (the legacy site-wide submit rule that forced white, a ring and navy on hover now
   exempts this one button, see 18.1.0.1). Rest is what it always was, transparent with only the icon showing. Transitions are the button's own four moving parts.
   S245 row 128, REOPENED (Rob 09/10 ~13:3x: "the magnifying glass sits within a little square with rounded corners. It's supposed to have a full border. And it can be a
   thinner border than the input fields border ... I'm also not so sure that the background colour is correct as it doesn't look like the proper light cream"): the 2px
   left-only rule with square left corners is REPLACED by a full border on all four sides and the radius on all four corners, both copied from .btn-option (43.1: "border: 1px
   solid var(--color-gold)" and "border-radius: 10px"), so it is thinner than the input's 2px border (25.2.6). It is TRANSPARENT here, so nothing shows or moves at rest, and it
   turns gold on hover (25.2.8). The 1px border on every side takes the place of the old 2px left border and 2px right padding, so the content box stays centred on the same
   point and the icon does not move. */
#buddypress #members_search_submit {
    position: absolute;
    top: 50%;
    right: 6px;
    transform: translateY(-50%);
    width: 36px;
    height: 32px;
    min-width: 0;
    padding: 0;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 10px;
    color: #031B83;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    align-self: center;
    box-shadow: none;
    transition: background 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease, transform 0.18s ease;
    box-sizing: border-box;
    z-index: 2;
}
/* end of 25.2.7 */

/* 25.2.8 Search submit hover: the site's button hover, the light cream (--color-cream, #FFFBE6: the painted fill measured exactly that on the live page) with the gold
   (--color-gold) border all round, whose left side is the gold rule Rob asked for on the 8th of October, and the same pop every button takes (the lift of 1px and the
   --shadow-gold-hover shadow, gated to a real pointer and stood down while held, as .btn-option at 43.1 and .btn--primary at 42.8); pressed is the darker cream
   (--color-cream-hover) with the border, no shadow and no lift (D-640). The lift is added to the button's own translateY(-50%) centring. */
#buddypress #members_search_submit:hover {
    background: var(--color-cream, #FFFBE6);
    border-color: var(--color-gold, #CC9900);
}
/* S246 item 128, 13/10/26 (Rob: "the gap above and below are not equal. They should be equal"): MEASURED on the live Members page at 1280 and 360, painted at 4 device
   pixels, hovered: input inner edge to the button's gold border was 1.00px above and 2.995px below, because this rule lifted the button 1px (translateY(calc(-50% - 1px)))
   off its centring. At rest it is 2px and 2px (input 40px, 2px borders, inner 36px, button 32px, no extra pixel needed as 36 - 32 is even). The lift is REMOVED so the
   hovered button keeps its centring and the gaps stay equal; the hover shadow stays. Source of the numbers: Rob's words and the measurement, nothing invented. */
@media (hover: hover) {
#buddypress #members_search_submit:hover:not(:active) {
    box-shadow: var(--shadow-gold-hover, 0 4px 12px rgba(0, 0, 0, 0.16));
}
}
#buddypress #members_search_submit:active {
    background: var(--color-cream-hover, #FFF5CC);
    border-color: var(--color-gold, #CC9900);
    box-shadow: none;
}
/* end of 25.2.8 */

/* 25.2.9 Search submit icon */
#buddypress #members_search_submit i,
#buddypress #members_search_submit .icon {
    color: #031B83;
    font-size: 16px;
}
/* end of 25.2.9 */

/* 25.2.10 Search input placeholder */
#buddypress #members-dir-search input::placeholder,
#buddypress .dir-search input::placeholder {
    color: rgba(3, 27, 131, 0.65) !important;
    opacity: 0.55 !important;
}
/* end of 25.2.10 */

/* 25.2.11 Search input focus */
html[data-nav="kbd"] #buddypress #members-dir-search input:focus,
html[data-nav="kbd"] #buddypress .dir-search input:focus {
    outline: none !important;
    border-color: #031B83 !important;
    box-shadow: 0 0 0 2px rgba(204, 153, 0, 0.25) !important;
}
/* end of 25.2.11 */
/* end of 25.2 */

/* 25.3 Order-by label + select — right-aligned so dropdown's right edge matches search row's right edge. Scoped to body.directory.members so the settings-page #subnav padding doesn't apply here. */
/* 25.3.1 Subnav container — full width */
body.directory.members #buddypress .item-list-tabs#subnav,
body.directory.members #buddypress #subnav {
    width: 100% !important;
    padding: 0 !important;
    overflow: visible !important;
}
/* end of 25.3.1 */

/* 25.3.2 Subnav ul — flex flex-end */
body.directory.members #buddypress .item-list-tabs#subnav > ul,
body.directory.members #buddypress #subnav > ul.list-unstyled,
body.directory.members #buddypress #subnav > ul {
    display: flex !important;
    justify-content: flex-end !important;
    width: 100% !important;
    margin: 0 !important;
    padding: 0 !important;
    gap: 10px !important;
}
/* end of 25.3.2 */

/* 25.3.3 Order-select li — flex centre */
body.directory.members #buddypress li#members-order-select {
    display: flex !important;
    align-items: center !important;
    gap: 10px !important;
    margin: 0 !important;
    padding: 0 !important;
    flex-shrink: 0 !important;
}
/* end of 25.3.3 */

/* 25.3.4 Order-select label — navy Nunito */
#buddypress #subnav #members-order-select label,
#buddypress li#members-order-select label {
    color: #031B83 !important;
    font-family: 'Nunito Sans', sans-serif !important;
    font-weight: 600 !important;
    font-size: 14px !important;
    margin: 0 !important;
}
/* end of 25.3.4 */

/* 25.3.5 Order-by select base */
#buddypress #members-order-by,
#buddypress select#members-order-by {
    background: #fffbe6 !important;
    border: 2px solid #CC9900 !important;
    border-radius: 8px !important;
    color: #031B83 !important;
    font-family: 'Nunito Sans', sans-serif !important;
    font-weight: 600 !important;
    font-size: 14px !important;
    padding: 0 32px 0 32px !important;
    height: 40px !important;
    cursor: pointer !important;
    text-align: center !important;
    text-align-last: center !important;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12) !important;
    transition: all 0.18s ease !important;
}
/* end of 25.3.5 */

/* 25.3.6 Order-by select option — centre */
#buddypress #members-order-by option {
    text-align: center !important;
}
/* end of 25.3.6 */

/* 25.3.7 Order-by select hover/focus */
#buddypress #members-order-by:hover,
#buddypress #members-order-by:focus {
    background: #CC9900 !important;
    border-color: #031B83 !important;
    color: #031B83 !important;
    outline: none !important;
}
/* end of 25.3.7 */
/* end of 25.3 */

/* 25.4 Single-row tabs layout — "All Members 9" on the left, "Order By"
   dropdown on the right, same horizontal baseline. AMENDMENT S58 2026-04-15:
   previously .item-list-tabs-wrapper rendered its two child .item-list-tabs
   divs on separate rows (All Members row, Order By row); Rob asked for a
   single row with reduced vertical space. */
/* 25.4.0.1 Tabs wrapper — flex row + space-between */
body.directory.members #buddypress .item-list-tabs-wrapper {
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: wrap !important;
    align-items: center !important;
    justify-content: space-between !important;
    gap: 8px 16px !important;
    width: 100% !important;
    margin: 0 0 10px 0 !important;
    padding: 0 !important;
}
/* end of 25.4.0.1 */

/* 25.4.0.2 Tabs wrapper ::before — invisible flex break */
/* Invisible flex break — sits between the reset button (order:-1) and
   the toolbar items (order:0), forcing the reset onto its own row */
body.directory.members #buddypress .item-list-tabs-wrapper::before {
    content: '' !important;
    order: 0 !important;
    flex: 0 0 100% !important;
    height: 0 !important;
}
/* end of 25.4.0.2 */

/* 25.4.0.3 Tabs wrapper @<=480px — centre + full width children */
@media (max-width: 480px) {
    body.directory.members #buddypress .item-list-tabs-wrapper {
        justify-content: center !important;
        gap: 8px !important;
    }
    body.directory.members #buddypress .item-list-tabs-wrapper > .item-list-tabs:not(#subnav),
    body.directory.members #buddypress .item-list-tabs-wrapper > .item-list-tabs#subnav {
        width: 100% !important;
        justify-content: center !important;
        text-align: center !important;
    }
}
/* end of 25.4.0.3 */

/* 25.4.0.3b Stacked toolbar — the Order By filter takes the upper row.
   S232 21/09/2026, Rob correction row 9: "make sure this is the same on all screen widths - on
   mobile they will likely need to be stacked with the filter at the top." MEASURED on the live
   page: the two controls share one row from 768 up and stack below it, because the toolbar is
   inset to the carousel window and a single card leaves it 310px, against the 321px the badge,
   the gap and the Order By control need. So the flip runs over exactly the band where they
   stack, and 768 and above are untouched, where order would swap them left to right instead.
   The search and reset row keeps its own order:-1 above both. */
@media (max-width: 767px) {
    body.directory.members #buddypress .item-list-tabs-wrapper > .item-list-tabs#subnav {
        order: 0 !important;
    }
    body.directory.members #buddypress .item-list-tabs-wrapper > .item-list-tabs:not(#subnav) {
        order: 1 !important;
    }
}
/* end of 25.4.0.3b */

/* 25.4.0.4 Tabs (non-subnav) child — auto sizing */
body.directory.members #buddypress .item-list-tabs-wrapper > .item-list-tabs:not(#subnav) {
    flex: 0 0 auto !important;
    width: auto !important;
    padding: 0 !important;
    margin: 0 !important;
    background: transparent !important;
    overflow: visible !important;
}
/* end of 25.4.0.4 */

/* 25.4.0.5 Tabs (non-subnav) ul — flex row */
body.directory.members #buddypress .item-list-tabs-wrapper > .item-list-tabs:not(#subnav) > ul {
    display: flex !important;
    flex-direction: row !important;
    gap: 10px !important;
    margin: 0 !important;
    padding: 0 !important;
    list-style: none !important;
}
/* end of 25.4.0.5 */

/* 25.4.0.6 Members-all li — flex centre */
body.directory.members #buddypress li#members-all {
    display: flex !important;
    align-items: center !important;
    margin: 0 !important;
    padding: 0 !important;
    background: transparent !important;
    border: 0 !important;
}
/* end of 25.4.0.6 */

/* 25.4.0.7 Members-all link — navy bold */
body.directory.members #buddypress li#members-all > a {
    display: inline-flex !important;
    align-items: center !important;
    /* S227 15/09/26, Rob: "the all members number badge at the bottom, it's too far away from
       the word members." Was 10px here plus BuddyPress's own 0.3rem on the span, 14.80px of ink
       to ink at 360 and 390 and 15.39px at 1280 because the rem drifts. 6px is the platform's
       own value for the same pattern, the Messages subnav count badge at 17.4.6.7, and a px
       value reads the same at every width. */
    gap: 6px !important;
    color: #031B83 !important;
    font-family: 'Nunito Sans', sans-serif !important;
    font-weight: 700 !important;
    font-size: 16px !important;
    padding: 0 !important;
    background: transparent !important;
    text-decoration: none !important;
    border: 0 !important;
}
/* end of 25.4.0.7 */

/* 25.4.1 Circle count badge — mirrors .sidenav-badge (light cream fill,
   gold border with darker bottom edge, navy numerals). */
body.directory.members #buddypress li#members-all > a > span {
    display: inline-flex !important;
    /* S227: buddypress.min.css gives every count span margin-left:0.3rem, which was adding a
       second gap on top of the anchor's. The anchor's gap is the only gap. */
    margin-left: 0 !important;
    align-items: center !important;
    justify-content: center !important;
    align-self: center !important;
    width: 22px !important;
    height: 22px !important;
    min-width: 22px !important;
    /* S207 05/09/26 - Rob: "the 51 bubble text is a pixel too high." Measured off the paint
       at 8x: the digits sat 0.875px above the ring centre, horizontally exact. padding-top is the
       only lever here - the box is a fixed 22x22 border-box flex centre, so a transform would move
       the ring with it, and the count is a bare text node that cannot be transformed on its own.
       Padding moves the ink by half its value and quantises, so the values were swept and measured
       rather than guessed: 0px and 1px render identically, 2px lands it. Was `padding: 0`. */
    /* S207 06/09/26, Rob item 12: digits one pixel to the right, done with 2px of padding-left,
       because padding moves the ink by half its value on this axis.
       S210 06/09/26: REVERSED on his word after seeing it measured. The digits were sitting
       0.56px right of the painted rings centre; taking the 2px of padding-left off moves the ink
       one pixel back to the left. The padding-top stays: that is the vertical centring. */
    /* S210, second pass: 0px left put the digits 0.44px LEFT of centre and 2px put them 0.56px
       RIGHT, so a pixel of padding is half a pixel of ink and 1px lands them on the middle. */
    /* S234 21/09/26, Rob: "the number on the all members badge is low and to the right too."
       RE-MEASURED against the PAINTED gold ring rather than the box, at device scale 8, 3 and 2
       and at 1, with every digit 0 to 9 and with 12 (Verification Suite/tools/s234_fix13_badge_ink.js,
       which proves itself each run by nudging the digit a known 4px of padding and reading 2px of
       ink back). The 1px of padding-left was NOT half a pixel of correction: it put every digit
       0.63px RIGHT of the ring centre at scale 8, and a full 0.50px right at scale 1, which is the
       lean Rob can see. With no padding-left the same sweep reads 0.13px, inside the half pixel.
       The vertical was already right and is kept: padding-top anywhere from 1px to 2px lands the
       digits 0.13px below the ring centre at scale 8 and dead on it at 2, 3 and 1.25, and 1.5px is
       the middle of that plateau rather than its edge, so a rounding change cannot tip it out.
       Was `padding: 2px 0 0 1px`. */
    padding: 1.5px 0 0 0 !important;
    border: 1px solid #CC9900 !important;
    /* S207 05/09/26 - the bottom edge was 2px against 1px on the other three, which on a
       circle reads as a smudge along the bottom arc. Rob spotted it by eye. Even ring now. */
    border-bottom-width: 1px !important;
    border-radius: 50% !important;
    /* S207 05/09/26 - was the non-brand #FFF0C2. BRAND_GUIDE (LOCKED) makes #FFFBE6 the brand
       cream and #FFF5CC the hover state only, so a resting count bubble takes the brand cream.
       Rob, 05/09/26: "all the others across the whole site need to be the same colour." */
    background: var(--color-cream) !important;
    color: #031B83 !important;
    font-family: 'Nunito Sans', sans-serif !important;
    font-size: 11px !important;
    font-weight: 700 !important;
    line-height: 1 !important;
    font-variant-numeric: tabular-nums !important;
    text-align: center !important;
    box-sizing: border-box !important;
    box-shadow: none !important;
}

/* 25.4.2 Order By container — override the earlier "width: 100% /
   justify-content: flex-end" rules so the #subnav hugs its content and
   sits on the right of the flex row rather than pushing to its own line. */
/* 25.4.2.1 Subnav inside wrapper — auto width */
body.directory.members #buddypress .item-list-tabs-wrapper > .item-list-tabs#subnav {
    width: auto !important;
    flex: 0 0 auto !important;
    margin: 0 !important;
    padding: 0 !important;
    overflow: visible !important;
}
/* end of 25.4.2.1 */

/* 25.4.2.2 Subnav ul inside wrapper — flex-end */
body.directory.members #buddypress .item-list-tabs-wrapper > .item-list-tabs#subnav > ul {
    width: auto !important;
    justify-content: flex-end !important;
    margin: 0 !important;
    padding: 0 !important;
}
/* end of 25.4.2.2 */
/* end of 25.4.2 */

/* 25.4.3 Vertical alignment — "All Members 9" label and "Order By:"
   label both forced to a 40px box so their text baselines match the
   "Last Active" text inside the dropdown. AMENDMENT S58 2026-04-15:
   Rob — labels previously sat ~9px below the dropdown text. Root
   cause of the offset: .custom-order-select div was 58px tall (40px
   button + 18px phantom space from Seeko defaults), pushing the
   flex-row center 9px lower than the button's own center. Fix:
   force .custom-order-select to 40px so every flex item in the row
   is the same height, then all three visually centre on one line. */
/* 25.4.3.1 Labels — 40px inline-flex centre */
body.directory.members #buddypress li#members-all > a,
body.directory.members #buddypress li#members-order-select > label,
body.directory.members #buddypress #subnav #members-order-select label {
    display: inline-flex !important;
    align-items: center !important;
    min-height: 40px !important;
    line-height: 1 !important;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
}
/* end of 25.4.3.1 */

/* 25.4.3.2 Custom order-select — locked 40px */
body.directory.members #buddypress #members-order-select .custom-order-select {
    height: 40px !important;
    min-height: 40px !important;
    max-height: 40px !important;
    display: block !important;
    padding: 0 !important;
    margin: 0 !important;
    line-height: 0 !important;
}
/* end of 25.4.3.2 */
/* end of 25.4.3 */

/* 25.5 Vertical spacing around the tabs row.
   AMENDMENT S58 2026-04-15 rev2 (T406): Rob "the distance between the
   last active box and the bottom of the search bar should be the same
   distance as the other side between the bottom of the last active box
   and the top of the gallery". Equal 16px gaps above and below the
   tabs row by zeroing the search/gallery side margins and putting all
   of the spacing on the tabs wrapper itself.
   AMENDMENT rev3 2026-04-15 (T406): z-index boost on the search bar
   and tabs row so the gallery window's outer navy halo box-shadow
   (§26.1.1) paints BEHIND them instead of bleeding over their bottoms.
   The gallery is later in DOM so its shadow layer paints on top of
   siblings by default; explicit z-index on earlier siblings restores
   the expected order. */
/* 25.5.1 Dir-search — zero margin + relative z-index */
body.directory.members #buddypress #members-dir-search,
body.directory.members #buddypress .dir-search {
    margin: 0 !important;
    position: relative !important;
    z-index: 5 !important;
    /* S59 2026-04-15 rev4: CSS padding approach retired. Form width + left position now set by JS in functions.php §6.7.3 — reads the live .members-gallery-window bounding rect and matches exactly, so the form is guaranteed to span from gallery-window-left to gallery-window-right regardless of upstream container differences. */
}
/* end of 25.5.1 */

/* 25.5.2 Tabs wrapper — 16px vertical margins */
body.directory.members #buddypress .item-list-tabs-wrapper {
    margin: 16px 0 16px 0 !important;
    position: relative !important;
    z-index: 5 !important;
}
/* end of 25.5.2 */

/* 25.5.3 Members-dir-list — zero top spacing + transition */
body.directory.members #buddypress #members-dir-list {
    margin-top: 0 !important;
    padding-top: 0 !important;
    transition: opacity 0.2s ease !important;
}
/* end of 25.5.3 */

/* 25.5.4 Members-dir-list — loading dim */
/* T406 S58 2026-04-15: immediate dim during BP AJAX (search / sort /
   reset). The §6.9 reset button adds .is-loading synchronously on
   click; the §6.7.3 parent observer removes it when BP finishes
   swapping in fresh content. Gives instant feedback instead of a
   dead two-second pause. */
body.directory.members #buddypress #members-dir-list.is-loading {
    opacity: 0.45 !important;
    pointer-events: none !important;
}
/* end of 25.5.4 */

/* 25.5.5 Gallery wrap — zero top margin */
body.directory.members .members-gallery-wrap {
    margin-top: 0 !important;
}
/* end of 25.5.5 */
/* end of 25.5 */

/* 25.6 (retired) — navy halo via window box-shadow was painting over
   the search bar + sort controls because the gallery is later in DOM
   than those elements. Replaced by §25.7. */

/* 25.7 (retired rev10) — Navy halo moved off #buddypress background
   and onto the .members-gallery-window box-shadow stack at §26.1.1.
   Background gradients on rectangular containers always leak a visible
   rectangle at the element edges ("what's with the rectangular edge
   that it just suddenly drops off at" — Rob, S58). A box-shadow with
   zero offset + large blur naturally fades radially around the window's
   rounded-rect border, no rectangle to drop off. Left here as a marker
   so future sessions don't re-add the gradient approach. */
body.directory.members #buddypress {
    background-image: none !important;
}
/* end of 25 */

/* ============================================================================
   26. SECTION: Members directory — single-row gallery, custom dropdown, postcode
   AMENDMENT S58 2026-04-14: grid → horizontal scrollable gallery with arrows,
   native Last Active select → custom branded dropdown, postcode area badge.
   ============================================================================ */

/* 26.1 Gallery wrapper — outer container that holds arrow buttons in its
   left/right padding area, OUTSIDE the gold-bordered window. The window
   itself does the clipping. AMENDMENT S58 2026-04-15 rev5: arrows moved
   outside the gold window per Rob, gold border added to inner window. */
/* 26.1.0.1 Gallery wrap — base padding */
body.directory.members .members-gallery-wrap {
    position: relative;
    width: 100%;
    max-width: 1400px;
    margin: 0 auto;
    padding: 0 15px;
    box-sizing: border-box;
    overflow: visible;
}
/* end of 26.1.0.1 */

/* end of 26.1 */

/* 26.1.1 Gallery window — the gold-bordered viewport that clips the
   horizontally-translating list. Cards that flow out either edge are
   clipped right at the gold border. AMENDMENT S58 2026-04-15 rev6: inset
   shadow stack so the window looks pushed into the page (3D). Order of
   shadows matters — inset darks first for the recessed feel, outer gold
   ambient last for the brand glow. */
body.directory.members .members-gallery-window {
    position: relative;
    width: 100%;
    overflow: hidden;
    border: 2px solid #CC9900;
    border-radius: 16px;
    background: #ffffff;
    /* S58 rev10 2026-04-15: navy halo returns as an OUTER box-shadow
       on the window itself (not a background gradient on #buddypress).
       A shadow with zero offset + large blur fades radially around the
       rounded-rect border, so there is no rectangular cut-off visible
       anywhere — the diffusion is in the blur profile, not a sharp
       edge on a container element. Matches Rob's mock from earlier in
       S58 ("soft navy outer glow around the gold border"). */
    box-shadow:
        /* inset stack — recessed 3D feel */
        inset 0 6px 14px rgba(0, 0, 0, 0.18),
        inset 0 -3px 10px rgba(0, 0, 0, 0.10),
        inset 6px 0 12px rgba(0, 0, 0, 0.10),
        inset -6px 0 12px rgba(0, 0, 0, 0.10),
        /* thin gold ambient */
        0 1px 0 rgba(255, 255, 255, 0.9),
        0 2px 10px rgba(204, 153, 0, 0.18),
        /* large navy halo — radial diffusion around the rounded border */
        0 0 110px 0 rgba(3, 27, 131, 0.45);
    box-sizing: border-box;
    padding: 15px;
}

/* 26.2 #members-list becomes a single-row carousel. Item 8 keeps 15px between
   full cards and 15px on every inside edge of the gallery window; partial-card
   peeks are not used. */
body.directory.members #buddypress #members-list {
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    gap: 15px !important;
    justify-content: flex-start !important;
    overflow: visible !important;
    padding: 0 !important;
    margin: 0 !important;
    list-style: none !important;
    /* Transform-based carousel — JS sets translateX, CSS animates it. */
    transform: translateX(0);
    transition: transform 350ms cubic-bezier(0.16, 1, 0.3, 1);
    will-change: transform;
}

/* 26.3 Item 8: one full card below 768, two from 768, three from 1280 and four
   at 1920. Section 6.7 measures the live window and reduces the 310px card only
   when necessary, so the agreed full-card count always fits without clipping. */
body.directory.members #buddypress #members-list li {
    flex: 0 0 var(--uks-member-card-width, 310px) !important;
    width: var(--uks-member-card-width, 310px) !important;
    max-width: 100% !important;
    min-width: 0 !important;
    margin: 0 !important;
    padding: 0 !important;
    background: transparent !important;
    border: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    box-sizing: border-box !important;
}
@media (max-width: 767px) {
    body.directory.members #buddypress #members-list li {
        flex: 0 0 100% !important;
        width: 100% !important;
    }
    /* and the card takes the li, so there is no dead strip beside it at 600 */
    body.directory.members #buddypress #members-list li > .uks-card {
        width: 100% !important;
    }
}

/* 26.4 Arrow buttons */
/* 26.4.1 Arrow base style — circular cream */
body.directory.members .members-gallery-arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: #fffbe6;
    border: 2px solid #CC9900;
    color: #031B83;
    font-size: 18px;
    font-weight: 700;
    font-family: 'Nunito Sans', sans-serif;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
    transition: all 0.2s ease;
    z-index: 10;
    padding: 0;
    line-height: 1;
}

body.directory.members .members-gallery-arrow .members-gallery-arrow-icon {
    width: 12px;
    height: 20px;
    display: block;
    flex: 0 0 12px;
}
body.directory.members .members-gallery-arrow-left .members-gallery-arrow-icon {
    transform: translateX(-1px);
}
body.directory.members .members-gallery-arrow-right .members-gallery-arrow-icon {
    transform: translateX(1px);
}
/* end of 26.4.1 */

/* 26.4.2 Arrow hover */
body.directory.members .members-gallery-arrow:hover,
body.directory.members .members-gallery-arrow:active {
    background: #FFF5CC;
    border-color: #CC9900;
    color: #031B83;
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.18);
}
/* end of 26.4.2 */

/* 26.4.3 Arrow left + right positions */
body.directory.members .members-gallery-arrow-left { left: 4px; }
body.directory.members .members-gallery-arrow-right { right: 4px; }
/* end of 26.4.3 */

/* 26.4.4 Arrow hidden state */
body.directory.members .members-gallery-arrow.is-hidden {
    opacity: 0;
    pointer-events: none;
}
/* end of 26.4.4 */
/* end of 26.4 */

/* 26.5 Custom Order By dropdown — replaces native <select> */
/* 26.5.1 Order-select wrapper */
body.directory.members .custom-order-select {
    position: relative;
    display: inline-block;
    /* S220 14/09/2026, Rob: "find the widest word, whichever one has the most
       letters or whatever, and then add fifteen pixel padding on either end, and
       then that is the fixed size of that box." MEASURED at this control's own
       font (Nunito Sans 600 14px): Nearest 51.37px, Last Active 74.70px, Newest
       Registered 125.27px. 125.27 + 15 + 15 + the caret (11px) and the 10px gap
       it already sits behind + 2px border each side = 182.27, taken to 182, and
       FIXED rather than a minimum so the box never changes size with the choice. */
    width: 182px;
    font-family: 'Nunito Sans', sans-serif;
}
/* end of 26.5.1 */

/* 26.5.2 Order-select button base */
body.directory.members .custom-order-select-btn {
    width: 100%;
    height: 40px;
    /* S220: 14px to 15px, Rob's number */
    padding: 0 15px;
    background: #fffbe6;
    border: 2px solid #CC9900;
    border-radius: 10px;
    color: #031B83;
    font-family: 'Nunito Sans', sans-serif;
    font-weight: 600;
    font-size: 14px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
    transition: all 0.2s ease;
    box-sizing: border-box;
}
/* end of 26.5.2 */

/* 26.5.3 Order-select button — open state.
   Rob 24/06/26: trigger bg STAYS cream (this is the per-page exception to
   the canonical white trigger); only the border flips to navy, caret
   rotates, shadow deepens. No gold-fill flip. */
/* F-077 (S234, 21/09/2026) SUPERSEDES THE BORDER HALF OF THE NOTE ABOVE. The entry is
   dropdown-gold-border-always: the gold edge is the dropdown's identity and stays while it is
   open. MEASURED before, on the live Members order-by at 1280: rgb(204,153,0) at rest and
   rgb(3,27,131) once open. The caret flip and the deeper shadow are untouched, so the control
   still reads as open. */
body.directory.members .custom-order-select.is-open .custom-order-select-btn {
    border-color: #CC9900;
    color: #031B83;
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.18);
}
/* end of 26.5.3 */

/* 26.5.4 Order-select label — flex 1, ellipsis */
body.directory.members .custom-order-select-label {
    flex: 1;
    text-align: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* end of 26.5.4 */

/* 26.5.5 Order-select caret */
body.directory.members .custom-order-select-caret {
    font-size: 12px;
    transition: transform 0.2s ease;
}
/* end of 26.5.5 */

/* 26.5.6 Order-select caret — flipped when open */
body.directory.members .custom-order-select.is-open .custom-order-select-caret {
    transform: rotate(180deg);
}
/* end of 26.5.6 */

/* 26.5.7 Order-select menu — popover */
/* AMENDMENT S58 2026-04-15 rev3 (T406): Restyled to match the
   interest-reasons popover at interest-system.php §7.1.3. Rob
   "use the same style as with the interested feature questionnaire
   pop up. All still too dark." White container, gold border, white
   option pills with faint navy borders, cream-bg gold-border on
   hover, soft-blue bg with navy border on selected. */
body.directory.members .custom-order-select-menu,
body.directory.members ul.custom-order-select-menu {
    display: flex !important;
    flex-direction: column !important;
    position: absolute !important;
    top: calc(100% + 10px) !important;
    right: 0 !important;
    left: auto !important;
    min-width: 220px !important;
    margin: 0 !important;
    padding: 14px !important;
    gap: 8px !important;
    list-style: none !important;
    background: #FFFFFF !important;
    border: 2px solid #CC9900 !important;
    border-radius: 12px !important;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18) !important;
    font-family: 'Nunito Sans', sans-serif !important;
    opacity: 0;
    visibility: hidden;
    transform: translateY(-4px);
    transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s ease;
    z-index: 98;                       /* S245 row 35 (Rob 07/10/26: "the drop down runs over the header ... No drop down anywhere on the site should be sticky like that. Obviously they should stick to the drop down, but they should stay on the page, not over the top of other elements."). MEASURED LIVE on the checkout year list with the page scrolled under the header: the list is position:absolute (it scrolls with the page, as Rob wants) at z-index 1000, the sticky header is z-index 99 (style.css 1041), so it painted over the header and the nav. One below the header, 98, for every dropdown list in this file, so a list that scrolls behind the header is covered by it and nothing else on the page is above it. Was 1000. */
}
/* end of 26.5.7 */

/* 26.5.8 Order-select menu — open state */
body.directory.members .custom-order-select.is-open .custom-order-select-menu {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}
/* end of 26.5.8 */

/* 26.5.9 Order-select option pill */
body.directory.members .custom-order-select-option,
body.directory.members li.custom-order-select-option {
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    width: 100% !important;
    flex: none !important;
    padding: 10px 14px !important;
    margin: 0 !important;
    background: #FFFFFF !important;
    border: 1.5px solid rgba(3, 27, 131, 0.2) !important;
    border-radius: 8px !important;
    color: #031B83 !important;
    font-family: 'Nunito Sans', sans-serif !important;
    font-weight: 600 !important;
    font-size: 13px !important;
    line-height: 1.2 !important;
    cursor: pointer !important;
    text-align: center !important;
    user-select: none !important;
    transition: all 0.15s ease !important;
    white-space: nowrap !important;
    list-style: none !important;
    box-sizing: border-box !important;
}
/* end of 26.5.9 */

/* 26.5.10 Order-select option hover */
body.directory.members .custom-order-select-option:hover {
    background: #fffbe6 !important;
    border-color: #CC9900 !important;
    color: #031B83 !important;
}
/* end of 26.5.10 */

/* 26.5.11 Order-select option — selected */
body.directory.members .custom-order-select-option.is-selected,
body.directory.members li.custom-order-select-option.is-selected {
    background: #fffbe6 !important;
    border-color: #CC9900 !important;
    color: #031B83 !important;
    font-weight: 700 !important;
}
/* end of 26.5.11 */

/* 26.5.12 Order-select option — selected hover */
body.directory.members .custom-order-select-option.is-selected:hover {
    background: #fffbe6 !important;
    border-color: #CC9900 !important;
    color: #031B83 !important;
}
/* end of 26.5.12 */
/* end of 26.5 */

/* 26.6 Postcode area badge — next to attendance badge, post-box icon.
   AMENDMENT S58 2026-04-15 rev2 (T406): Rob "the postcode and the
   attendance counter buttons should be the same size and style."
   Unified to match §18.6 .member-attendance-badge — same padding,
   border, radius, font, colour, margin. */
/* 26.6.1 Postcode badge base
   S159: .member-age-badge dropped from this selector. D-278 forbids showing any member's age on
   any surface, and the emitter was deleted from functions.php 6.6a, so the selector had nothing
   left to match. Removed rather than left dangling (D-243). */
#buddypress #members-list .member-postcode-badge {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    align-self: center !important;
    gap: 3px !important;
    background: #fff !important;
    border: 1px solid #CC9900 !important;
    border-radius: 12px !important;
    /* S133 D-260: 12px -> 8px side padding. The row gained a third badge (age)
       inside a 118px .item; at 12px the pills escaped the card. Height is
       unchanged (4px top/bottom), so the pills stay the same size and style as
       the attendance badge per Rob's T406 rule - only the horizontal breathing
       room is trimmed to make room for age. */
    padding: 4px 8px !important;
    font-family: 'Montserrat', sans-serif !important;
    font-size: 11px !important;
    font-weight: 600 !important;
    color: #031B83 !important;
    line-height: 1 !important;
    margin-top: 10px !important;
}
/* end of 26.6.1 */

/* 26.6.2 Postcode badge icon (S159: the age icon selector removed with the badge, D-278) */
#buddypress #members-list .member-postcode-badge .postcode-icon {
    font-size: 13px !important;
    line-height: 1 !important;
    display: inline-flex !important;
    align-items: center !important;
}
/* end of 26.6.2 */
/* end of 26.6 */

/* 26.7 Bottom row pair — postcode left, attendance right. Wrapper is
   injected by the JS in §6.9. Both badges sit on one horizontal row
   so they read as a "where / how often" summary at the foot of each
   card. T406 S58 2026-04-15. */
/* 26.7.1 Bottom-pair wrapper — flex row
   S133 D-260: the row now carries a THIRD badge (age), and .item is only 118px
   wide. Measured: age 61.2 + postcode 60.5 + 8 gap = 136 in a 118 box, so the
   postcode pill physically ESCAPED the card's right edge. Two fixes, both
   needed: centre + wrap here, and tighter pill padding in 26.6.1.
   - justify-content centre (was space-between): with three items space-between
     strands the middle one and, once wrapped, leaves a lone left-aligned badge
     on line 2. Centred wraps symmetrically ("Symmetry is King").
   - flex-wrap wrap: three pills CANNOT fit on one 118px line at any sane pill
     size, so the row must be allowed a second line rather than overflow. Most
     cards show only age + postcode (attendance renders only when count > 0),
     and those fit on one line at the tightened padding. */
#buddypress #members-list .member-bottom-pair {
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: wrap !important;
    justify-content: center !important;
    align-items: center !important;
    gap: 6px !important;
    width: 100% !important;
    margin-top: 10px !important;
    padding: 0 4px !important;
    box-sizing: border-box !important;
}
/* end of 26.7.1 */

/* 26.7.2 Reset child margin-top so wrapper-margin applies only */
/* Reset the individual badges' own margin-top so only the wrapper
   margin applies — otherwise they get double-spaced. */
#buddypress #members-list .member-bottom-pair .member-postcode-badge,
#buddypress #members-list .member-bottom-pair .member-attendance-badge {
    margin-top: 0 !important;
    flex: 0 0 auto !important;
}
/* end of 26.7.2 */
/* end of 26.7 */

/* 26.8 "Reset search results" button — own centred row between search bar
   and toolbar. order:-1 puts it above the All Members/Order By items.
   flex-basis:100% forces it onto its own line in the wrapping flex row. */
/* 26.8.1 Reset button base */
body.directory.members #members-search-reset {
    order: -1 !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    align-self: center !important;
    margin: 0 auto 8px !important;
    height: 34px !important;
    padding: 0 16px !important;
    background: #fffbe6 !important;
    border: 2px solid #CC9900 !important;
    border-radius: 10px !important;
    color: #031B83 !important;
    font-family: 'Nunito Sans', sans-serif !important;
    font-size: 13px !important;
    font-weight: 700 !important;
    line-height: 1 !important;
    letter-spacing: 0.2px !important;
    cursor: pointer !important;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12) !important;
    transition: all 0.2s ease !important;
    white-space: nowrap !important;
    z-index: 3 !important;
}
/* end of 26.8.1 */

/* 26.8.2 Reset button hover */
body.directory.members #members-search-reset:hover {
    /* S222 14/09/26, Rob: "on hover the reset search results button turns gold, it should be light
       cream turns gold cream on hover and select". BRAND_GUIDE's own amendment v1.1 (08/09/26) says
       the same in the tab spec: the hover is #FFF5CC, the darker cream, not #CC9900 gold. */
    background: var(--color-cream-hover, #FFF5CC) !important;
    color: #031B83 !important;
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.18) !important;
}
/* end of 26.8.2 */

/* 26.8.3 Reset button — full-strength request-in-flight state */
body.directory.members #members-search-reset[aria-busy="true"] {
    background: #fffbe6 !important;
    color: #031B83 !important;
    border-color: #CC9900 !important;
    opacity: 1 !important;
    filter: none !important;
    cursor: progress !important;
    box-shadow: none !important;
}
/* end of 26.8.3 */
/* end of 26.8 */
/* end of 26 */

/* ============================================================================
   27. SECTION: About Us page — members gallery (flat variant)
   T404 S58 2026-04-15: Rob "copy the exact member cards from this
   membership page and just do the same thing. Just put a scroll and
   gallery on the about us page... but don't have any of the 3D
   effects, don't have the inner shadow or outer gradient, just have
   the border." Scoped to body.page-id-926.

   Pairs with §6.8 about_us_members_gallery() in functions.php which
   renames the Seeko widget UL id from members-list-grid to members-list
   so every card-interior style in §5/§6 above applies for free.

   Override the old vertical-stack rules at §1.3 that forced 4 cards
   into a single column. Those used .uksp-widget-members-grid
   #members-list-grid selectors; since JS now renames the id, the old
   rules no longer match and we re-layout cleanly here.
   ============================================================================ */

/* 27.0 About Us #buddypress root — the JS in §6.8 injects a synthetic
   <div id="buddypress" class="about-us-bp-root"> around the Seeko
   widget container so card CSS scoped "#buddypress #members-list ..."
   catches on this page. This rule neutralises any inherited BP chrome
   (padding, bg, borders) from rules that target plain #buddypress so
   the synthetic wrapper is transparent. */
body.page-id-926 #buddypress.about-us-bp-root {
    background: transparent !important;
    padding: 0 !important;
    margin: 0 !important;
    border: 0 !important;
    box-shadow: none !important;
    max-width: none !important;
}

/* 27.1 Outer wrapper — 56px gutter for arrow buttons like §26.1. */
body.page-id-926 .about-us-members-gallery-wrap {
    position: relative;
    width: 100%;
    max-width: 100%;
    padding: 0 56px;
    margin: 0 auto;
    box-sizing: border-box;
    overflow: visible;
}

/* 27.2 Flat window variant — gold border only. No inset shadows, no
   outer gradient halo, no background gradient. Plain white viewport
   that clips horizontally-translating cards. */
body.page-id-926 .members-gallery-window,
body.page-id-926 .members-gallery-window--flat {
    position: relative;
    width: 100%;
    overflow: hidden;
    border: 2px solid #CC9900;
    border-radius: 16px;
    background: #ffffff;
    box-shadow: none;
    box-sizing: border-box;
}

/* 27.3 Row layout — override the Seeko widget's Bootstrap .row + col-*
   stacking and force a single horizontal flex row. Transform-based
   carousel mirrors §26.2. */
body.page-id-926 #buddypress #members-list,
body.page-id-926 .uksp-widget-members-grid #members-list {
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    gap: 5% !important;
    overflow: visible !important;
    padding: 28px 0 28px !important;
    margin: 0 !important;
    width: auto !important;
    max-width: none !important;
    list-style: none !important;
    transform: translateX(0);
    transition: transform 350ms cubic-bezier(0.16, 1, 0.3, 1);
    will-change: transform;
}

/* 27.4 Cards — 20% width each (5 cards visible, half-peek on each side).
   The Seeko widget applies Bootstrap col-md-* classes for its grid
   layout; we have to beat every likely variant.
   AMENDMENT S58 2026-04-15 rev2: DO NOT zero padding. The shared rule
   at line 472 gives the li its 28px 20px 22px padding, which is what
   creates the visible gap between the background card (li) and the
   foreground card (.item-container nested inside). Zeroing padding
   collapsed the foreground onto the background and killed the stack.
   Only flex/width/margin/float need overriding here. */
body.page-id-926 #buddypress #members-list > li,
body.page-id-926 .uksp-widget-members-grid #members-list > li,
body.page-id-926 #members-list > li[class*="col-"] {
    flex: 0 0 20% !important;
    width: 20% !important;
    max-width: 20% !important;
    min-width: 0 !important;
    margin: 0 !important;
    float: none !important;
    box-sizing: border-box !important;
}

/* 27.4a Cards per view, by width. S141 21/07/26, Rob (mobile screenshot):
   "about page is supposed to have a grid but it's broken... it's trying to show
   loads of members when it should only be showing one."

   MEASURED CAUSE, not guessed: 27.4 above pinned every slide to 20% at EVERY
   viewport, so the carousel always tried to fit five cards across. At a 390px
   viewport the gallery window is 214px, so each card computed to 42px wide and
   the cards collapsed into each other exactly as the screenshot shows. The li
   also carries only col-sm-6 and up from the Seeko widget, so below 576px
   Bootstrap contributes no width at all and there was nothing to catch it.

   The fix is to make the slide count responsive rather than fixed: five across
   on a large desktop, down to ONE on a phone. The carousel's own step maths
   reads the live card width, so it follows this automatically. */
@media (max-width: 1199.98px) {
    body.page-id-926 #buddypress #members-list > li,
    body.page-id-926 .uksp-widget-members-grid #members-list > li,
    body.page-id-926 #members-list > li[class*="col-"] {
        flex-basis: 25% !important;
        width: 25% !important;
        max-width: 25% !important;
    }
}
@media (max-width: 991.98px) {
    body.page-id-926 #buddypress #members-list > li,
    body.page-id-926 .uksp-widget-members-grid #members-list > li,
    body.page-id-926 #members-list > li[class*="col-"] {
        flex-basis: 33.3333% !important;
        width: 33.3333% !important;
        max-width: 33.3333% !important;
    }
}
@media (max-width: 767.98px) {
    body.page-id-926 #buddypress #members-list > li,
    body.page-id-926 .uksp-widget-members-grid #members-list > li,
    body.page-id-926 #members-list > li[class*="col-"] {
        flex-basis: 50% !important;
        width: 50% !important;
        max-width: 50% !important;
    }
}
@media (max-width: 575.98px) {
    body.page-id-926 #buddypress #members-list > li,
    body.page-id-926 .uksp-widget-members-grid #members-list > li,
    body.page-id-926 #members-list > li[class*="col-"] {
        flex-basis: 100% !important;
        width: 100% !important;
        max-width: 100% !important;
    }
    /* The 56px desktop gutter at 27.1 leaves only ~214px of window on a phone,
       which is what made a single card feel cramped even once it was alone.
       The arrows still need somewhere to sit, so this trims rather than removes. */
    body.page-id-926 .about-us-members-gallery-wrap {
        padding: 0 40px !important;
    }
}

/* 27.5 Arrow buttons — mirror §26.4 but scoped to page 926. */
/* 27.5.1 Arrow base — circular cream */
body.page-id-926 .members-gallery-arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: #fffbe6;
    border: 2px solid #CC9900;
    color: #031B83;
    font-size: 18px;
    font-weight: 700;
    font-family: 'Nunito Sans', sans-serif;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
    transition: all 0.2s ease;
    z-index: 10;
    padding: 0;
    line-height: 1;
}
/* end of 27.5.1 */

/* 27.5.2 Arrow hover */
body.page-id-926 .members-gallery-arrow:hover {
    background: #CC9900;
    border-color: #031B83;
    color: #031B83;
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.18);
}
/* end of 27.5.2 */

/* 27.5.3 Arrow left + right positions */
body.page-id-926 .members-gallery-arrow-left  { left: 4px; }
body.page-id-926 .members-gallery-arrow-right { right: 4px; }
/* end of 27.5.3 */

/* 27.5.4 Arrow hidden state */
body.page-id-926 .members-gallery-arrow.is-hidden {
    opacity: 0;
    pointer-events: none;
}
/* end of 27.5.4 */
/* end of 27.5 */
/* end of 27 */

/* ============================================================================
   28. SECTION: Events page spacing + nav dropdown fixes
   ============================================================================ */

/* 28.10 Events search/filter block — on-brand */
/* 28.10.1 Filter section card */
.events-filter-section {
    background: #FFFFFF !important;
    border: 2px solid #CC9900 !important;
    border-radius: 12px !important;
    padding: 14px 16px !important;
    box-shadow: 0 1px 3px rgba(0,0,0,0.05) !important;
}
/* end of 28.10.1 */

/* 28.10.2 Filter row secondary — flex baseline centre */
.events-filter-row-secondary {
    display: flex !important;
    align-items: baseline !important;
    justify-content: center !important;
}
/* end of 28.10.2 */

/* 28.10.3 Search input — gold border */
.events-search-input {
    background: #ffffff !important;
    border: 2px solid #CC9900 !important;
    border-radius: 8px !important;
    font-family: 'Nunito Sans', sans-serif !important;
    font-size: 14px !important;
    padding: 10px 12px !important;
    color: #031B83 !important;
    /* S198: promoted from the max-width:1023px block with the selects, which that
       block already treats as one group - leaving this one left-aligned at desktop
       while its two neighbours centre would be the odd control in the row. */
    text-align: center !important;
}
.events-search-input::placeholder {
    text-align: center;
}
/* end of 28.10.3 */

/* 28.10.4 Search/filter inputs — force white bg */
/* S77 Rob item 26: force white bg on autofill, focus, active too. Seeko
   and some browser extensions tint inputs light-blue-grey — override. */
.events-search-input,
.events-search-input:focus,
.events-search-input:active,
.events-search-input:hover,
.events-filter-row input[type=text],
.events-filter-row input[type=search],
.events-filter-form input[type=text],
.events-filter-form input[type=search] {
    background: #ffffff !important;
    background-color: #ffffff !important;
}
/* end of 28.10.4 */

/* 28.10.5 Search input — autofill override */
.events-search-input:-webkit-autofill,
.events-search-input:-webkit-autofill:hover,
html[data-nav="kbd"] .events-search-input:-webkit-autofill:focus {
    -webkit-box-shadow: 0 0 0 1000px #ffffff inset !important;
    -webkit-text-fill-color: #031B83 !important;
}
/* end of 28.10.5 */

/* 28.10.6 Search input focus */
html[data-nav="kbd"] .events-search-input:focus {
    border-color: #CC9900 !important;
    box-shadow: 0 0 0 2px rgba(204,153,0,0.15) !important;
    outline: none !important;
}
/* end of 28.10.6 */

/* 28.10.7 Filter select base */
.events-filter-select {
    border: 1px solid rgba(26,26,46,0.08) !important;
    border-radius: 8px !important;
    font-family: 'Nunito Sans', sans-serif !important;
    font-size: 14px !important;
    padding: 10px !important;
    color: #1A1A2E !important;
    /* S198 29/08/26, Rob: "the content on these drop down buttons should be centred
       and not left aligned". The centring already existed but ONLY inside
       @media (max-width: 1023px) below, so the directory filters read centred on a
       phone and left-aligned on a desktop. Promoted to the base rule so it holds at
       every width, on all three directories that share this class.
       `text-align` alone does NOT move a <select>'s displayed value - that needs
       `text-align-last` - and the option list is styled separately below. */
    text-align: center !important;
    text-align-last: center !important;
}
.events-filter-select option {
    text-align: center;
}
/* end of 28.10.7 */

/* 28.10.8 Filter select focus */
html[data-nav="kbd"] .events-filter-select:focus {
    border-color: #CC9900 !important;
    box-shadow: 0 0 0 2px rgba(204,153,0,0.15) !important;
    outline: none !important;
}
/* end of 28.10.8 */

/* 28.10.9 Filter button base */
.events-filter-button {
    background: #fffbe6 !important;
    color: #031B83 !important;
    border: 2px solid #CC9900 !important;
    border-radius: 10px !important;
    padding: 10px 20px !important;
    font-family: 'Nunito Sans', sans-serif !important;
    font-size: 14px !important;
    font-weight: 600 !important;
    box-shadow: var(--shadow-gold-hover) !important;
    cursor: pointer !important;
    transition: all 0.18s ease !important;
}
/* end of 28.10.9 */

/* 28.10.10 Filter button hover */
.events-filter-button:hover {
    /* S207 05/09/26, Rob item A4: hover fills with the DARKER cream, not gold. */
    background: var(--color-cream-hover, #FFF5CC) !important;
    color: #031B83 !important;
    border-color: #CC9900 !important;
}
/* end of 28.10.10 */

/* 28.10.11 Filter reset — text link */
.events-filter-reset {
    color: #031B83 !important;
    font-family: 'Nunito Sans', sans-serif !important;
    font-size: 14px !important;
    font-weight: 600 !important;
    height: 40px !important;
    display: inline-flex !important;
    align-items: center !important;
    text-decoration: none !important;
}
/* end of 28.10.11 */

/* S217 09/09/2026: the venue Verified tick became an inline SVG, and an inline SVG's box sits
   on the text baseline, so it rode 5px above the badge's own centre line (measured on the
   live card at six times scale: badge midpoint 929.61, tick midpoint 924.61). Centring it
   on the line box rather than nudging it by a number, so it stays right if the badge's
   font size ever changes. */
.venue-badge.venue-verified svg,
.venue-badge svg {
    vertical-align: middle;
    /* `middle` aligns to the baseline plus half the x-height, not to the line box centre,
       which left 1.34px measured on the live badge. This is that, and only that. */
    transform: translateY(-1.34px);
}

/* S217 09/09/2026: `.btn-option` sets `display: inline-flex !important`, which beats an inline
   `style="display:none"` and beats the JS that slides an option away. The venue invite is
   where that bit: the "Buy a ticket" payment card is printed hidden and slid up on a venue
   invite, and it rendered at 228x30 anyway. An element the server or the script has
   explicitly hidden must stay hidden, whatever else it is. */
.btn-option[style*="display:none"],
.btn-option[style*="display: none"],
.btn-option[hidden] {
    display: none !important;
}

/* S217 09/09/2026: the checkout's discount code control, which is where EARLYBIRD is typed. The
   other lane made it visible again after a login-page rule had been collapsing it to nothing.
   Measured live afterwards: the field and the Apply button already carry their 2px gold borders,
   so the only thing left plain was the link that opens the box, navy and underlined with nothing
   to mark it as the way in. Gold, like every other link on the platform. */
#other_discount_code_toggle,
#other_discount_code_p a {
    color: var(--color-gold, #CC9900) !important;
    font-weight: 700 !important;
}
#other_discount_code_toggle:hover,
#other_discount_code_p a:hover {
    color: var(--color-navy, #031B83) !important;
}

/* S217 09/09/2026 (EV-25), the other three surfaces that can show a placeholder. Same reason:
   the fallback image is transparent now, so the container has to carry the brand gradient. */
.event-card-image--has-sigil,
figure.img-dynamic img.avatar,
.bio-avatar img.avatar {
    /* !important because the bio widget's avatar carries a flat navy `background`
       shorthand further down, and a shorthand resets background-image. */
    background-image: linear-gradient(145deg, #041D88, #0A2A9E) !important;
    background-size: cover !important;
}
/* S219 (Rob 10/09/26, CUST-124): the two avatar surfaces also carry the gold person and a gold border.
   Not the card banner above, which is a banner rather than a sigil. */
figure.img-dynamic img.avatar,
.bio-avatar img.avatar {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='3.75 4.19 16.5 17.8'%3E%3Cpath d='M4.6 21.14c0-4.1 3.3-6.6 7.4-6.6s7.4 2.5 7.4 6.6z' fill='%23CC9900'/%3E%3Ccircle cx='12' cy='8.74' r='3.7' fill='%23CC9900'/%3E%3C/svg%3E"), linear-gradient(145deg, #041D88, #0A2A9E) !important;
    background-repeat: no-repeat, no-repeat !important;
    background-position: center 50%, center !important;
    background-size: 46%, cover !important;
    border: 2px solid #CC9900 !important;
}

/* 28.10.13 S217 09/09/2026: the venue filter notice the other lane's EV-31 build prints between
   the filter box and the grid. It arrived with no rules of its own and rendered as 18px Nunito
   Sans at weight 400, left aligned on a page that centres everything else. Montserrat 15/600
   navy and centred, with the clear link in gold so it reads as the action in the sentence.
   (Checked while here: `.events-filter-reset` was reported as painting grey #666. It does not,
   it measures navy #031B83 live; the grey is in an older rule that no longer wins.) */
.events-page-wrapper .events-active-filter {
    font-family: var(--font-heading, 'Montserrat'), sans-serif !important;
    font-size: 15px !important;
    font-weight: 600 !important;
    color: var(--color-navy, #031B83) !important;
    text-align: center !important;
    margin: 0 0 14px !important;
}
.events-page-wrapper .events-active-filter__clear {
    color: var(--color-gold, #CC9900) !important;
    font-weight: 700 !important;
    height: auto !important;
    text-decoration: underline !important;
}
.events-page-wrapper .events-active-filter__clear:hover {
    color: var(--color-navy, #031B83) !important;
}
/* end of 28.10.13 */

/* 28.10.12 Filter reset hover */
.events-filter-reset:hover {
    color: #CC9900 !important;
}
/* end of 28.10.12 */
/* end of 28.10 */

/* 28.1 Breathing room — Events title → Featured Events heading (reduced 15%) */
/* 28.1.1 Heading titles — bottom margin */
body:has(.events-page-wrapper) .uksp-heading-title,
body:has(.events-page-wrapper) .entry-title,
body:has(.events-page-wrapper) .page-title {
    margin-bottom: 21px !important;
}
/* end of 28.1.1 */

/* 28.1.2 Featured section title — padding/margin */
.events-featured-section .events-section-title {
    padding-bottom: 20px !important;
    margin-bottom: 29px !important;
}
/* end of 28.1.2 */

/* 28.1.3 Featured scroll — top margin */
.events-featured-section .events-featured-scroll {
    margin-top: 14px !important;
}
/* end of 28.1.3 */
/* end of 28.1 */

/* 28.1.4 Full width: extra 20% gap between featured cards and search box */
@media (min-width: 1280px) {
    .events-featured-section {
        margin-bottom: 72px !important; /* 60px + 20% */
    }
}

/* 28.2 Search/filter box — tablet: 80% width, centered, 20% more margin */
@media (min-width: 768px) and (max-width: 1023px) {
    .events-filter-section {
        width: 80% !important;
        margin-left: auto !important;
        margin-right: auto !important;
        margin-top: 36px !important;
        margin-bottom: 36px !important;
    }
}

/* 28.2.1 Tablet/mobile search box: center all content */
/* Tablet/mobile: center ALL search container content */
@media (max-width: 1023px) {
    .events-filter-section {
        text-align: center !important;
    }
    .events-filter-form {
        text-align: center !important;
    }
    .events-filter-row {
        flex-direction: column !important;
        align-items: center !important;
        justify-content: center !important;
    }
    .events-filter-row-secondary {
        justify-content: center !important;
        align-items: baseline !important;
        flex-direction: row !important;
        gap: 12px !important;
    }
    .events-search-input,
    .events-filter-select {
        width: 100% !important;
        flex: none !important;
        /* S198: the centring that used to live here is now in the base rules, so it
           applies at every width. Only the mobile stacking values remain. */
    }
    .events-filter-button {
        margin: 0 !important;
    }
    .events-filter-reset {
        margin: 0 !important;
    }
}

/* All viewports: search container bottom margin +10% (30→33px) */
.events-filter-section {
    margin-bottom: 38px !important;
}

/* Full width (≥1280): also increase top margin */
@media (min-width: 1280px) {
    .events-filter-section {
        margin-top: 33px !important;
    }
}

/* 28.10.4a S224 15/09/26, Rob items 94 and 103 - the gap above the filter card.
   The 33px above belongs to /events/ and is right there, so it is not edited. On the two
   DIRECTORY pages it collapses with the header's 26px and holds the gap at 45px when Rob
   asked for it reduced. Scoped by page id, the same way 52.5 scopes this panel's width.
   MEASURED at 1280 and 1920: 45px without this, 38px with it - uniform with the 38px the
   same card already has below it. */
@media (min-width: 1280px) {
    body.page-id-6898 .events-page-wrapper .events-filter-section,
    body.page-id-6944 .events-page-wrapper .events-filter-section {
        margin-top: 26px !important;
    }
}

/* S74 Rob 2026-04-20 — deleted the legacy rule that hid the 4th featured card
   on non-tablet widths. Rob's new policy: show all 4 featured at every width,
   grid breakpoints in §31.4 handle how they stack. */

/* 28.4 ALL event cards — identical styling for both .events-grid and .events-featured-scroll */
/* 28.4.1 Event card — gold border + reset constraints */
.events-page-wrapper .event-card,
.events-featured-scroll .event-card {
    border: 2px solid #CC9900 !important;
    overflow: hidden !important;
    min-width: 0 !important;
    max-width: none !important;
    flex-shrink: unset !important;
    width: auto !important;
}
/* end of 28.4.1 */

/* 28.4.2 Featured scroll grid — match events-grid */
/* Featured scroll → same grid as .events-grid */
.events-featured-scroll {
    display: grid !important;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)) !important;
    gap: 16px !important; /* S230 17/09/2026, Rob: "Gap to 16px" - three 310px cards plus two 16px gaps is 962px in the 965px the page gives at 1280, so three fit. */
    overflow-x: visible !important;
    padding-bottom: 0 !important;
}
/* end of 28.4.2 */

/* 28.4.3 Card height @>=1024 — 347px */
/* Full width + desktop (≥1024): 347px fixed */
@media (min-width: 1024px) {
    .events-grid .event-card,
    .events-featured-scroll .event-card {
        min-height: 347px !important; height: auto !important;
    }
}
/* end of 28.4.3 */

/* 28.4.4 Tablet 768-1023 — 2-col 300px */
/* Tablet (768–1023): 2-column, 300px fixed. Below 768 the cards are too thin
   for two columns, so falls through to §28.4.5 single-col layout. */
@media (min-width: 768px) and (max-width: 1023px) {
    .events-grid,
    .events-featured-scroll {
        grid-template-columns: repeat(2, 1fr) !important;
    }
    .events-grid .event-card,
    .events-featured-scroll .event-card {
        min-height: 300px !important; height: auto !important;
    }
}
/* end of 28.4.4 */

/* 28.4.5 Mobile <768 — single col 360px */
/* Mobile (<768): fixed height + single column for featured */
@media (max-width: 767px) {
    .events-grid .event-card,
    .events-featured-scroll .event-card {
        min-height: 360px !important; height: auto !important;
    }
    .events-featured-scroll {
        grid-template-columns: 1fr !important;
    }
}
/* end of 28.4.5 */
/* end of 28.4 */

/* REMOVED: Section 28.6a nav dropdown centering — Venues/Organisers now top-level,
   dropdown no longer exists. Previously verified centering revoked as unnecessary. */

/* 28.11.7 Base grid — needed on ALL pages using .events-grid (events, venues, organisers) */
.events-grid {
    display: grid !important;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)) !important;
    gap: 16px !important;
}

/* 28.11 Organiser + Venue cards — proper spacing, centering, footer at bottom */
/* 28.11.1 Card — flex column */
.events-grid .event-card {
    display: flex !important;
    flex-direction: column !important;
}
/* end of 28.11.1 */

/* 28.11.2 Card body — flex 1 + centre */
.events-grid .event-card .event-card-body {
    flex: 1 !important;
    display: flex !important;
    flex-direction: column !important;
    text-align: center !important;
}
/* end of 28.11.2 */

/* 28.11.3 Card title — centre */
.events-grid .event-card .event-card-title {
    text-align: center !important;
}
/* end of 28.11.3 */

/* 28.11.4 Card excerpt — centre */
.events-grid .event-card .event-card-excerpt {
    text-align: center !important;
}
/* end of 28.11.4 */

/* 28.11.5 Card footer — flex column centre, push bottom */
.events-grid .event-card .event-card-footer {
    margin-top: auto !important;
    text-align: center !important;
    display: flex !important;
    flex-direction: column !important;
    justify-content: center !important;
    align-items: center !important;
    gap: 8px !important;
}
/* end of 28.11.5 */

/* 28.11.6 Wishlist/interest button — centred */
/* Venue/organiser "Show Interest" / "Interested?" button */
.wishlist-button,
.interest-btn {
    margin: 0 auto !important;
    display: inline-flex !important;
    align-items: center !important;
}
/* end of 28.11.6 */

/* 28.11.8 S227 (vw5, hand-off H3). THE org_follow AND venue_save WIDGET BUTTONS SIT HARD LEFT
   INSIDE THEIR WIDGET BODY. Measured live on the customise editor at 360, 390, 414, 768, 1024,
   1280 and 1920: the gap from the widget body's content box to the LEFT of the button is 0.00px at
   every one of those widths, and the gap on its RIGHT is 131.57 to 136.72px (org_follow) and 113.28
   to 130.05px (venue_save). The BUTTON itself is already correct and is not touched: 78.39px round
   a 52.39px label and 107.81px round an 81.81px label, which is the label plus 43.1's own 12px
   padding and 1px border each side, identical at every width.
   CAUSE: 28.11.6 above already declares this control "centred" and cannot deliver it here. `margin:
   0 auto` does not centre an INLINE-level box, and 28.11.6 sets `display: inline-flex` in the same
   block; and 43.1's `.btn-option { margin: 0 !important }` beats it on source order regardless
   (measured margin on the live button: 0px / 0px). `.widget-body` is `display: block`, so an
   inline-level child is placed by `text-align`, which nothing sets on it, so it inherits `left`.
   One declaration on those two widget bodies only. Verified with this rule injected on the live
   site: every `.wishlist-button` on /events/, /venues/ and /organisers/ measured byte-identical.
   NOT CHANGED HERE, DELIBERATELY: the widget BOX is 209.97 to 237.86px of content box around a 78
   to 108px button. Shrinking the box to its content is D-535's own answer ("the content should
   always fill the widget window") and belongs to the widget-sizing lane, not to this rule. If that
   lands, this rule costs nothing: a button that fills its body centres to the same place. */
.profile-widget[data-widget-id="org_follow"] > .widget-body,
.profile-widget[data-widget-id="venue_save"] > .widget-body {
    text-align: center;
}
/* end of 28.11.8 */

/* end of 28.11 */

/* 28.12 Organiser/venue search filter — base flex + center on all viewports */
.events-filter-row {
    display: flex !important;
    gap: 12px !important;
    flex-wrap: wrap !important;
    justify-content: center !important;
    align-items: center !important;
}

/* 28.6 Category badge — restyle to match date badge (white bg, gold border, navy text) */
.event-card-badge {
    background: #FFFFFF !important;
    color: #031B83 !important;
    border: 2px solid #CC9900 !important;
    border-radius: 8px !important;
    padding: 4px 8px !important;
    font-size: 12px !important;
    font-weight: 600 !important;
    box-shadow: 0 1px 3px rgba(26, 26, 46, 0.08) !important;
    top: 12px !important;
    left: 12px !important;
}

/* 28.7 Venue text — centered + space after map pin icon */
/* 28.7.1 Venue text — block centre */
.event-card-venue {
    text-align: center !important;
    display: block !important;
}
/* end of 28.7.1 */

/* 28.7.2 Venue ::before — icon spacing */
.event-card-venue::before {
    margin-right: 4px !important;
}
/* end of 28.7.2 */
/* end of 28.7 */

/* 28.8 Date badge — gold border to match category badge */
.event-card-date {
    border: 2px solid #CC9900 !important;
}

/* 28.5 Event grid — 60px gap on tablet and up (mobile keeps base) */
@media (min-width: 768px) {
    .events-page-wrapper .events-grid,
    .events-page-wrapper .events-featured-scroll {
        gap: 60px !important;
    }
}
/* end of 28 */

/* ============================================================================
   29. My Events workspace page (T460, 2026-04-17)
   Dashboard workspace for Organisers + Venues + Admins to manage their events.
   Slug: /members/<user>/my-events/
   ============================================================================ */

/* 29.1 Page container */
.my-events-page {
    font-family: "Nunito Sans", sans-serif;
    padding: 24px 0;
    text-align: center;
    max-width: 100%;
}

/* 29.2 Dead-centre Add-an-Event button */
/* 29.2.1 Header container — flex centre */
.my-events-header {
    display: flex;
    justify-content: center;
    margin-bottom: 28px;
}
/* end of 29.2.1 */

/* 29.2.2 Add button base */
.my-events-add-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: #fffbe6;
    color: #031B83;
    border: 2px solid #CC9900;
    padding: 10px 28px;
    border-radius: 16px;
    font-family: Montserrat, sans-serif;
    font-weight: 700;
    font-size: 16px;
    text-decoration: none;
    box-shadow: 0 2px 6px rgba(0,0,0,.12);
    transition: transform 150ms ease, box-shadow 150ms ease, background 150ms ease;
    line-height: 1.2;
}
/* end of 29.2.2 */

/* 29.2.3 Add button hover/focus */
.my-events-add-btn:hover,
html[data-nav="kbd"] .my-events-add-btn:focus {
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(0,0,0,.18);
    color: #031B83;
    background: #fff5cc;
}
/* end of 29.2.3 */

/* 29.2.4 Add button dashicon */
.my-events-add-btn .dashicons {
    font-size: 18px;
    width: 18px;
    height: 18px;
    line-height: 1;
    color: #031B83;
}
/* end of 29.2.4 */
/* end of 29.2 */

/* 29.3 Search + date filter — TWO rows: row 1 = search input (centred, own line), row 2 = From + date + To + date + Filter + Reset (inline).
   Uses !important on the flex mechanics because BuddyPress + Seeko reset `form` to display:block at higher specificity and that cascades down. */
/* 29.3.1 Search form — flex column */
.my-events-page form.my-events-search {
    display: flex !important;
    flex-direction: column !important;
    align-items: center !important;
    gap: 18px !important;
    margin: 0 auto 28px !important;
    width: 100% !important;
    max-width: 100% !important;
}
/* end of 29.3.1 */

/* 29.3.2 Date row — flex no-wrap */
.my-events-page form.my-events-search .my-events-search-daterow {
    display: flex !important;
    flex-wrap: nowrap !important;
    flex-direction: row !important;
    justify-content: center !important;
    align-items: center !important;
    gap: 8px !important;
    width: 100% !important;
    overflow-x: auto !important;
    padding-bottom: 4px !important;
}
/* end of 29.3.2 */

/* 29.3.3 Date row children — 44px height baseline */
.my-events-page form.my-events-search .my-events-search-daterow > * {
    box-sizing: border-box !important;
    height: 44px !important;
    flex-shrink: 0 !important;
    font-family: Montserrat, sans-serif !important;
    font-size: 14px !important;
    line-height: 44px !important;
    display: inline-flex !important;
    align-items: center !important;
    vertical-align: middle !important;
    width: auto !important;
}
/* end of 29.3.3 */

/* 29.3.4 Search text input */
.my-events-page form.my-events-search input.my-events-search-text {
    flex: 1 1 220px !important;
    min-width: 180px !important;
    max-width: 340px !important;
    padding: 0 18px !important;
    border: 2px solid #CC9900 !important;
    border-radius: 16px !important;
    color: #031B83 !important;
    background: #fff !important;
    font-size: 14px !important;
    line-height: 40px !important;
    height: 44px !important;
}
/* end of 29.3.4 */

/* 29.3.5 Search text placeholder */
.my-events-search-text::placeholder {
    color: rgba(3, 27, 131, 0.65);
    opacity: 0.55;
}
/* end of 29.3.5 */

/* 29.3.6 Search text focus */
html[data-nav="kbd"] .my-events-search-text:focus {
    outline: none;
    box-shadow: 0 0 0 2px rgba(204,153,0,0.25);
}
/* end of 29.3.6 */

/* 29.3.7 Date input */
.my-events-page form.my-events-search input[type="date"] {
    padding: 0 14px !important;
    border: 2px solid #CC9900 !important;
    border-radius: 16px !important;
    color: #031B83 !important;
    background: #fff !important;
    font-size: 14px !important;
    line-height: 40px !important;
    width: 160px !important;
    min-width: 150px !important;
    max-width: 180px !important;
    height: 44px !important;
}
/* end of 29.3.7 */

/* 29.3.8 Date input focus */
html[data-nav="kbd"] .my-events-search input[type="date"]:focus {
    outline: none;
    box-shadow: 0 0 0 2px rgba(204,153,0,0.25);
}
/* end of 29.3.8 */

/* 29.3.9 Search label */
.my-events-search-label {
    padding: 0 4px;
    font-weight: 700;
    color: #031B83;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    font-size: 13px;
    transform: translateY(-3px); /* Nudge label text up 3px to align with the date input's visible "dd/mm/yyyy" text baseline (Chrome renders date input text slightly below box centre due to the picker icon). */
}
/* end of 29.3.9 */

/* 29.3.10 Submit button base */
.my-events-page form.my-events-search button {
    padding: 0 22px !important;
    background: #fffbe6 !important;
    color: #031B83 !important;
    border: 2px solid #CC9900 !important;
    border-radius: 16px !important;
    font-weight: 700 !important;
    cursor: pointer;
    font-size: 14px !important;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    transition: background 150ms ease;
    height: 44px !important;
}
/* end of 29.3.10 */

/* 29.3.11 Submit button hover */
.my-events-search button:hover {
    background: #fff5cc;
}
/* end of 29.3.11 */

/* 29.3.12 Reset link */
.my-events-reset {
    padding: 0 8px;
    color: #031B83;
    font-size: 13px;
    font-weight: 700;
    text-decoration: underline;
}
/* end of 29.3.12 */

/* 29.3.13 Reset link hover */
.my-events-reset:hover {
    color: #CC9900;
}
/* end of 29.3.13 */
/* end of 29.3 */

/* 29.3.14 Verification pending notice — shown to level-4/5 users whose _organiser_verified / _venue_verified meta is not 'approved' */
.my-events-verification-notice {
    max-width: 720px;
    margin: 0 auto 24px;
    padding: 14px 24px;
    background: #fffbe6;
    border: 2px solid #CC9900;
    border-radius: 16px;
    color: #031B83;
    font-family: Montserrat, sans-serif;
    font-weight: 600;
    font-size: 14px;
    text-align: center;
    line-height: 1.4;
}

/* 29.4 Events grid (user's own events) */
/* 29.4.1 Grid layout */
.my-events-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 20px;
    padding: 0;
    text-align: left;
}
/* end of 29.4.1 */

/* 29.4.2 Event card base */
.my-events-card {
    background: #fff;
    border: 2px solid #CC9900;
    border-radius: 16px;
    padding: 20px;
    box-shadow: 0 2px 6px rgba(0,0,0,.12);
    display: flex;
    flex-direction: column;
    gap: 12px;
    transition: transform 150ms ease, box-shadow 150ms ease;
}
/* end of 29.4.2 */

/* 29.4.3 Event card hover */
.my-events-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 20px rgba(0,0,0,.12);
}
/* end of 29.4.3 */

/* 29.4.4 Card head — flex right */
.my-events-card-head {
    display: flex;
    justify-content: flex-end;
}
/* end of 29.4.4 */

/* 29.4.5 Status pill base */
.my-events-status {
    font-size: 11px;
    font-weight: 600;
    padding: 3px 12px;
    border-radius: 9999px;
    font-family: Montserrat, sans-serif;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
/* end of 29.4.5 */

/* 29.4.6 Status pill — publish (green) */
.my-events-status.status-publish { background: var(--color-success-bg); color: var(--color-success); }
/* end of 29.4.6 */

/* 29.4.7 Status pill — pending (gold) */
.my-events-status.status-pending { background: rgba(204,153,0,0.12); color: #CC9900; }
/* end of 29.4.7 */

/* 29.4.8 Status pill — draft (grey) */
.my-events-status.status-draft   { background: rgba(107,114,128,0.12); color: #6B7280; }
/* end of 29.4.8 */

/* 29.4.9 Status pill — future (navy) */
.my-events-status.status-future  { background: rgba(3,27,131,0.08); color: #031B83; }
/* end of 29.4.9 */

/* 29.4.10 Card title */
.my-events-card-title {
    font-family: Montserrat, sans-serif;
    font-weight: 700;
    font-size: 18px;
    color: #031B83;
    margin: 0;
    line-height: 1.3;
}
/* end of 29.4.10 */

/* 29.4.11 Card meta — flex column */
.my-events-card-meta {
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: 14px;
    color: #4b5563;
}
/* end of 29.4.11 */

/* 29.4.12 Card meta dashicon */
.my-events-card-meta .dashicons {
    color: #CC9900;
    margin-right: 4px;
    font-size: 16px;
    width: 16px;
    height: 16px;
    vertical-align: middle;
}
/* end of 29.4.12 */

/* 29.4.13 Card price */
.my-events-card-price {
    font-weight: 700;
    color: #CC9900;
    font-size: 15px;
}
/* end of 29.4.13 */

/* 29.4.14 Card actions row */
.my-events-card-actions {
    display: flex;
    gap: 8px;
    margin-top: auto;
}
/* end of 29.4.14 */

/* 29.4.15 Edit + view buttons — shared base */
.my-events-edit-btn,
.my-events-view-btn {
    flex: 1;
    text-align: center;
    padding: 8px 12px;
    border-radius: 16px;
    font-weight: 700;
    text-decoration: none;
    font-size: 13px;
    font-family: Montserrat, sans-serif;
    transition: transform 150ms ease, background 150ms ease;
}
/* end of 29.4.15 */

/* 29.4.16 Edit button — navy filled */
.my-events-edit-btn {
    background: #031B83;
    color: #CC9900;
    border: 2px solid #031B83;
}
/* end of 29.4.16 */

/* 29.4.17 Edit button hover */
.my-events-edit-btn:hover {
    color: #CC9900;
    background: #0a2daa;
    transform: translateY(-1px);
}
/* end of 29.4.17 */

/* 29.4.18 View button — outline */
.my-events-view-btn {
    background: transparent;
    color: #031B83;
    border: 2px solid #CC9900;
}
/* end of 29.4.18 */

/* 29.4.19 View button hover */
.my-events-view-btn:hover {
    color: #031B83;
    background: #fffbe6;
    transform: translateY(-1px);
}
/* end of 29.4.19 */
/* end of 29.4 */

/* 29.5 Empty state — brand navy copy, no secondary CTA (top Add button is the only entry point) */
/* 29.5.1 Empty state container */
.my-events-empty {
    text-align: center;
    padding: 60px 20px;
    color: #031B83;
}
/* end of 29.5.1 */

/* 29.5.2 Empty state paragraph */
.my-events-empty p {
    font-size: 16px;
    margin: 0;
    font-family: Montserrat, sans-serif;
    font-weight: 600;
}
/* end of 29.5.2 */
/* end of 29.5 */

/* 29.6 Form wrap — centres the [submit_event] form in the workspace */
/* 29.6.1 Page form wrapper — max 820px centred */
.my-events-page-form {
    max-width: 820px;
    margin: 0 auto;
    text-align: center;
}
/* end of 29.6.1 */

/* 29.6.2 Form wrap — left-aligned, centred container */
.my-events-form-wrap {
    text-align: left;
    margin: 0 auto;
}
/* end of 29.6.2 */

/* 29.6.3 Submit form wrapper — centred */
.my-events-form-wrap .event-submit-form-wrapper {
    text-align: center;
}
/* end of 29.6.3 */

/* 29.6.4 Submit form heading h2 */
.my-events-form-wrap .event-submit-form-wrapper h2 {
    font-family: Montserrat, sans-serif;
    color: #031B83;
    font-weight: 700;
    margin-bottom: 24px;
}
/* end of 29.6.4 */

/* 29.6.5 Submit form fields — left aligned */
.my-events-form-wrap .event-submit-form {
    text-align: left;
}
/* end of 29.6.5 */

/* 29.6.6 Back button */
.my-events-back-btn {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-bottom: 20px;
    color: #031B83;
    text-decoration: none;
    font-weight: 700;
    font-size: 14px;
    font-family: Montserrat, sans-serif;
}
/* end of 29.6.6 */

/* 29.6.7 Back button hover */
.my-events-back-btn:hover {
    color: #CC9900;
}
/* end of 29.6.7 */

/* 29.6.8 Back button dashicon */
.my-events-back-btn .dashicons {
    font-size: 16px;
    width: 16px;
    height: 16px;
}
/* end of 29.6.8 */
/* end of 29.6 */

/* 29.7 Small screens — stack the search row, single-column grid */
@media (max-width: 768px) {
    .my-events-search {
        flex-direction: column;
        align-items: stretch;
    }
    .my-events-search input[type="text"] {
        min-width: auto;
        width: 100%;
    }
    .my-events-search label {
        justify-content: space-between;
    }
    .my-events-grid {
        grid-template-columns: 1fr;
    }
}
/* end of 29 */

/* ============================================================================
   30. SECTION: S63 Phase 1c — Uniformity Pass (Rob S62 Table B sign-off +
       T455 Table C + D089/D090/D091 + LB-022/023/024)
   ============================================================================ */

/* 30.1 Event card uniform size (Table B B31/B32/B35 sign-off) — no half-width
        collapse at 1024, identical card size between .events-grid and
        .events-featured-scroll. Desktop (>=1280) = auto-fit 280px cards at 347
        tall; tablet / small-desktop (810-1279) = 2 cols at 248 wide 360 tall;
        mobile (<810) = single col 248 wide 360 tall. Gold border and brand
        chrome inherited from §28.4. Ranges per D091 (locked base at 360). */
/* 30.1.1 Grid base — flex/grid + auto-margin centre */
.events-page-wrapper .events-grid,
.events-page-wrapper .events-featured-scroll,
.events-featured-scroll,
.events-grid {
    display: grid !important;
    gap: 16px !important;
    justify-content: center !important;
    margin-left: auto !important;
    margin-right: auto !important;
}
/* end of 30.1.1 */

/* 30.1.2 Wrapper @<=1279px — centre + auto margins */
/* S76 Rob pt2: at ≤1279 Rob reported cards offset left on 810/768/360.
   Force the wrapper inside the page section to be centred so the grid's
   own centring lands symmetrically. */
@media (max-width: 1279px) {
    .events-page-wrapper,
    .events-page-wrapper .events-section,
    .events-page-wrapper .events-featured-section {
        text-align: center !important;
        margin-left: auto !important;
        margin-right: auto !important;
    }
}
/* end of 30.1.2 */

/* 30.1.3 Grid forced max-content + auto centring */
/* S76-006 Rob: `scrollbar-gutter: stable both-edges` was shrinking the
   header's usable width by 2× scrollbar width, pushing Contact Us off
   screen site-wide. Removed. Events grid centring is now achieved via
   per-grid margin:auto + justify-content:center alone. */
/* S77 Rob review items 1/2/17/19:
   - Same card WIDTH at every breakpoint (280px) so columns look identical.
   - Same card HEIGHT at every breakpoint (380px) so location+price don't push the
     'Free/paid' label into awkward positions.
   - Columns: <810=1, 810-1007=2, 1008+=3, 1920+=4. 1008 threshold (not 1024)
     so that 1024-target screens with scrollbar chrome still get 3 columns.
   - Forced horizontal centring via width:max-content + margin-inline:auto —
     this overrides any parent padding asymmetry (item 17 /da-style fix). */
.events-page-wrapper .events-grid,
.events-page-wrapper .events-featured-scroll,
.events-featured-scroll,
.events-grid {
    width: max-content !important;
    max-width: 100% !important;
    margin-inline: auto !important;
    justify-self: center !important;
}
/* end of 30.1.3 */

/* 30.1.4 Mobile <810 — 1 column 280px cards */
@media (max-width: 767px) {
    /* S77 Rob: max-content + margin-inline:auto for centring + parent
       padding reset so there's no leftover asymmetric Seeko/Elementor
       padding pushing the grid right at 360.
       S80 Rob 2026-04-29: threshold moved from 809 to 767 — anything less
       than 768 screen width goes to one column. 768+ uses §30.1.5 (2 col). */
    .events-page-wrapper,
    .events-page-wrapper .events-period-section,
    .events-page-wrapper .events-featured-section,
    .events-page-wrapper .events-section {
        padding-left: 0 !important;
        padding-right: 0 !important;
    }
    .events-page-wrapper .events-grid,
    .events-page-wrapper .events-featured-scroll,
    .events-featured-scroll,
    .events-grid {
        grid-template-columns: 280px !important;
        width: max-content !important;
        margin-left: auto !important;
        margin-right: auto !important;
    }
    .events-page-wrapper .event-card,
    .events-featured-scroll .event-card,
    .events-grid .event-card {
        min-height: 380px !important; height: auto !important;
        width: 280px !important;
    }
}
/* end of 30.1.4 */

/* 30.1.5 Tablet 768-1023 — 2 columns 280px */
/* (S80 Rob 2026-04-29: threshold moved from 810 to 768 to match the canonical
   tablet/mobile breakpoint used elsewhere in the file.) */
@media (min-width: 768px) and (max-width: 1023px) {
    .events-page-wrapper .events-grid,
    .events-page-wrapper .events-featured-scroll,
    .events-featured-scroll,
    .events-grid {
        grid-template-columns: repeat(2, 280px) !important;
    }
    .events-page-wrapper .event-card,
    .events-featured-scroll .event-card,
    .events-grid .event-card {
        min-height: 380px !important; height: auto !important;
        width: 280px !important;
    }
    /* Featured row caps at 2 cards here per Rob 26/06/26 single-row rule. */
    .events-featured-scroll .event-card:nth-child(n+3),
    .events-featured-scroll .uks-card:nth-child(n+3) {
        display: none !important;
    }
}
/* end of 30.1.5 */

/* 30.1.6 Desktop 1024-1439 — 3 columns 280px */
/* Upper bound dropped 1919 → 1439 per Rob 26/06/26: anything at or above
   1440 shows 4 columns (not the old 1920 threshold which never fired on
   maximised Chrome at 1920 display because of the scrollbar). */
@media (min-width: 1024px) and (max-width: 1439px) {
    .events-page-wrapper .events-grid,
    .events-page-wrapper .events-featured-scroll,
    .events-featured-scroll,
    .events-grid {
        grid-template-columns: repeat(3, 280px) !important;
    }
    .events-page-wrapper .event-card,
    .events-featured-scroll .event-card,
    .events-grid .event-card {
        min-height: 380px !important; height: auto !important;
        width: 280px !important;
    }
    /* Featured row stays SINGLE ROW per Rob 26/06/26 — PHP fetches up to 8
       events but Featured should show only as many as the grid has columns
       at the current breakpoint. Hide the 4th+ featured card at 3-col widths
       so they don't wrap. (Search-results grid below the filter is unaffected
       — only .events-featured-scroll has this nth-child cap.) */
    .events-featured-scroll .event-card:nth-child(n+4),
    .events-featured-scroll .uks-card:nth-child(n+4) {
        display: none !important;
    }
}
/* end of 30.1.6 */

/* 30.0.5 Events archive — period-section pagination styling. Reuses the
   .att-pagination markup but events archive isn't inside .workspace so the
   workspace-scoped button rule at line 13981 doesn't reach. Restate it
   scoped to .events-pag. Also kill overflow-anchor so the §10 height
   transition doesn't fight the browser's scroll-anchor (per skill §10). */
.events-period-section {
    overflow-anchor: none;
}
.events-grid {
    overflow-anchor: none;
}

/* 30.0.6 Period-section grids switch to flex per Rob 26/06/26: CSS grid
   left-aligns partial last rows; flex with `justify-content: center` centres
   them automatically (a lone card sits dead-centre; 2 of 4 sit in cols 2-3;
   etc). Max-width per breakpoint constrains the row to the right col count
   so the wrap point lands at the same width the grid rule used to. Excludes
   the organiser-directory variant which uses its own grid rule downstream. */
.events-period-section .events-grid:not(.organiser-directory-grid) {
    display: flex !important;
    flex-wrap: wrap !important;
    justify-content: center !important;
    gap: 16px !important; /* S230 17/09/2026, Rob: "Gap to 16px" so three 310px cards fit the 965px the page gives at 1280. */
    margin-left: auto !important;
    margin-right: auto !important;
}

/* 30.0.6a S168 — THE SAME FIX, APPLIED TO THE TWO DIRECTORIES THAT NEVER GOT IT.
   Rob decided this on 26/06/26 (§30.0.6 above) and it was scoped to the events archive only, so the
   venue and organiser directories kept the grid behaviour it exists to correct. MEASURED anonymously
   at 1280: /venues/ one card in a 3-col grid sat 304px LEFT of centre; /organisers/ one card in a
   2-col grid sat 182px left. The events archive, on flex, centred every row including a lone card.
   That is Visual Design Rule 1 (symmetry) broken on two public directories, and it is not a fixture
   artefact - it recurs whenever the count is not an exact multiple of the column number, which is
   most of the time.
   ⚠️ §30.0.6's exclusion says the organiser variant "uses its own grid rule downstream". IT DOES NOT.
   `organiser-directory-grid` appears in this stylesheet ONLY inside that :not(), and its sizing rule
   lives in an inline <style> in event-system.php (~13385). The comment is stale and sent me looking
   for a rule that was never written (LB-222 - a stale comment is a trap for the next agent).
   flex-basis originally kept the card widths the grid rules gave them: 280px venues, 310px
   organisers. S218 made BOTH 310px: see the note on the card rule below. */
/* S218: the .events-page-wrapper prefix is load-bearing. Without it this rule ties on
   specificity with 31.4.1 further down (.events-page-wrapper .events-grid, gap 20px at
   <=480px) and loses on document order, so at 360 the venue grid took a 20px gap while the
   organiser grid kept 24px from its own inline style. Both directory grids are inside
   .events-page-wrapper. */
.events-page-wrapper .events-grid.venue-directory-grid,
.events-page-wrapper .events-grid.organiser-directory-grid {
    display: flex !important;
    flex-wrap: wrap !important;
    justify-content: center !important;
    /* S220 14/09/2026, T-S218-056. Rob at 1280: "at that screen width, there's room for three
       columns. So there should be three columns of events. Not two." MEASURED: the grid's own
       container is 965px and the card is 310px, so three cards need 930px of card plus the gaps.
       At 24px the row wants 978 and only two fit; at 16px it wants 962 and three do. 16px is the
       brand's own --sp-lg step, so this is a step down the scale rather than an invented number. */
    gap: 16px !important;
    margin-left: auto !important;
    margin-right: auto !important;
}
/* 30.0.6b S218 (T-S217-061). Rob, 09/09/2026, on the two directories: "why? They should all be
   the exact same style for consistency." MEASURED anonymously at 1280 before this rule: the
   venue card was 280 x 450.59 with a 160px banner and a 20px gap, the organiser card 310 x
   538.97 with a 200px banner and a 24px gap. The venue side had simply kept the events-archive
   sizing, while the organiser side carries its own sizing in an inline <style> at
   mu-plugins/event-system.php ~15044 (310px column, 24px gap, 420px min-height, 200px banner).
   The organiser values are now declared for BOTH directories here, so the two cards are one
   style. Note the leading .events-page-wrapper on the last two rules: without it the banner
   rule ties on specificity with 31.3.1 further down this file (which pins every event-card
   banner at 160px) and loses on document order. The remaining height difference between a
   venue and an organiser card is CONTENT, not style: the organiser card carries a
   p.event-card-excerpt and the venue card only emits one when the venue has a tagline. */
.events-page-wrapper .events-grid.venue-directory-grid > .event-card,
.events-page-wrapper .events-grid.organiser-directory-grid > .event-card {
    flex: 0 1 310px !important;
}
.events-page-wrapper .events-grid.venue-directory-grid .event-card,
.events-page-wrapper .events-grid.organiser-directory-grid .event-card {
    min-height: 420px !important;
    height: auto !important;
}
.events-page-wrapper .events-grid.venue-directory-grid .event-card .event-card-image,
.events-page-wrapper .events-grid.organiser-directory-grid .event-card .event-card-image {
    min-height: 200px !important;
    height: 200px !important;
}
/* end of 30.0.6a */
@media (min-width: 768px) and (max-width: 1023px) {
    .events-period-section .events-grid:not(.organiser-directory-grid) {
        /* 2 × 280 + 1 × 20 = 580px */
        /* Rob, 08/09/2026, on Coming Up at 1024: "it just seems to not be centered. Look at it
               compared to the featured section. It is just off to the right. So that whole section
               just needs to copy the settings of the featured section." The featured strip is
               max-width 100% and fills its 608px column exactly; these three were pinned to a
               card-count width with no reference to the column, so at 1024 the grid painted 880px
               inside 608px and hung 64px off the screen. min() keeps the card-count intent AND
               never exceeds the column. */
            max-width: min(580px, 100%) !important;
    }
}
@media (min-width: 1024px) and (max-width: 1439px) {
    .events-period-section .events-grid:not(.organiser-directory-grid) {
        /* S230 17/09/2026: the cards measure 310px, not 280, so this 880px cap (3 x 280 + 2 x 20)
           allowed only two per row at 1280 while Featured fitted three. Raised to 3 x 310 + 2 x 16
           = 962px, which is what the Featured strip measures, so both sections match. */
        max-width: min(962px, 100%) !important;
    }
}
@media (min-width: 1440px) {
    .events-period-section .events-grid:not(.organiser-directory-grid) {
        /* 4 × 280 + 3 × 20 = 1180px */
        max-width: min(1180px, 100%) !important;
    }
}
.events-pag.att-pagination {
    margin-top: var(--sp-xl);
}
/* D-640/D-651 (S235 SHADOWS-5, 25/09/26): was transparent with no rest shadow; the brief for
   this group said it becomes the standard button, so rest becomes the full cream/gold/
   gold-shadow standard, not just a shadow bolt-on. */
.events-pag .att-pagination__btn {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    width: 32px !important;
    height: 32px !important;
    padding: 0 !important;
    border-radius: 50% !important;
    border: 1.5px solid var(--color-gold) !important;
    background: var(--color-cream) !important;
    color: var(--color-navy) !important;
    cursor: pointer !important;
    margin: 0 !important;
    box-shadow: var(--shadow-gold-hover) !important;
    transition: background var(--duration-fast) var(--ease-out) !important;
}
.events-pag .att-pagination__btn:hover:not(:disabled) {
    background: var(--color-cream) !important;
}
/* D-651: pressed carries no shadow, and there was no active rule at all here. */
.events-pag .att-pagination__btn:active:not(:disabled) {
    background: var(--color-cream-hover) !important;
    box-shadow: none !important;
}
.events-pag .att-pagination__btn:disabled {
    opacity: 0.35 !important;
    cursor: not-allowed !important;
}
.events-pag .att-pagination__info {
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 13px;
    color: var(--color-navy);
    min-width: 70px;
    text-align: center;
}

/* 30.1.7 Widescreen >=1440 — 4 columns 280px */
/* Threshold dropped 1920 → 1440 per Rob 26/06/26: "anything from 1440
   upwards shows 4". Replaces the old 1920 cut-off. */
@media (min-width: 1440px) {
    .events-page-wrapper .events-grid,
    .events-page-wrapper .events-featured-scroll,
    .events-featured-scroll,
    .events-grid {
        grid-template-columns: repeat(4, 280px) !important;
    }
    .events-page-wrapper .event-card,
    .events-featured-scroll .event-card,
    .events-grid .event-card {
        min-height: 380px !important; height: auto !important;
        width: 280px !important;
    }
    /* Featured row caps at 4 cards here so it stays single-row even when PHP
       returns more (it fetches up to 8). Search-results grid below is unaffected. */
    /* S230 17/09/2026, Rob: "if there are two rows and it is three columns wide, then they are
       just six featured events... the whole point is it looks uniform and neat." At 1440 and up the
       strip fits three per row, so the cap moves from four (which left a ragged 3+1) to three, one
       full row. Six would need six featured events; there are four. */
    .events-featured-scroll .event-card:nth-child(n+4),
    .events-featured-scroll .uks-card:nth-child(n+4) {
        display: none !important;
    }
}
/* end of 30.1.7 */
/* end of 30.1 */

/* 30.2 Event-card date (B42/B43 sign-off) — navy Montserrat, larger readable
        size, replaces the single grey 13px block. Day/month span split (B46/B47)
        is still pending Rob sign-off — styling applies to whatever element
        currently renders. */
.event-card .event-card-date,
.events-grid .event-card-date,
.events-featured-scroll .event-card-date {
    color: #031B83 !important;
    font-family: 'Montserrat', sans-serif !important;
    font-weight: 700 !important;
    font-size: 14px !important;
    background: rgba(255, 255, 255, 0.92) !important;
    border-radius: 12px !important;
}

/* 30.3 .events-filter-button (B50 sign-off) — LB-023 canonical cream/gold/navy. */
/* 30.3.1 Filter button base */
.events-filter-button,
.events-filter-section button[type="submit"],
.events-filter-form button[type="submit"] {
    background: #fffbe6 !important;
    color: #031B83 !important;
    border: 2px solid #CC9900 !important;
    border-radius: 10px !important;
    font-family: 'Montserrat', sans-serif !important;
    font-weight: 700 !important;
    padding: 10px 24px !important;
    transition: background 160ms ease, transform 120ms ease, box-shadow 160ms ease;
}
/* end of 30.3.1 */

/* 30.3.2 Filter button hover */
.events-filter-button:hover,
.events-filter-section button[type="submit"]:hover,
.events-filter-form button[type="submit"]:hover {
    background: #fff5cc !important;
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.16) !important;
}
/* end of 30.3.2 */
/* end of 30.3 */

/* 30.4 Event filter inputs (B56 sign-off) — gold hairline, navy text. No greys. */
/* 30.4.1 Filter inputs/select base */
.events-filter-row input[type="text"],
.events-filter-row input[type="search"],
.events-filter-row select,
.events-filter-section input[type="text"],
.events-filter-section input[type="search"],
.events-filter-section select {
    border: 2px solid #CC9900 !important;
    color: #031B83 !important;
    font-family: 'Nunito Sans', sans-serif !important;
    border-radius: 16px !important;
    background: #ffffff !important;
}
/* end of 30.4.1 */

/* 30.4.2 Filter input placeholder */
.events-filter-row input::placeholder,
.events-filter-section input::placeholder {
    color: rgba(3, 27, 131, 0.65) !important;
}
/* end of 30.4.2 */
/* end of 30.4 */

/* 30.5 Events search bar width (B57 sign-off) — 90% of gallery width at every
        viewport; gallery itself maxes at 1440 desktop, 90% of viewport at tablet
        / mobile. Mirrors members-gallery rule. */
.events-page-wrapper .events-filter-section,
.events-page-wrapper .events-filter-form {
    width: 90% !important;
    max-width: 1296px !important; /* 90% of 1440 gallery */
    margin-left: auto !important;
    margin-right: auto !important;
}

/* 30.6 T460 submit-event form bottom brand correction — file inputs, native
        color picker, helper text, labels. LB-023 / LB-024. */
/* 30.6.1 Form labels — Montserrat navy */
.event-submit-form label,
.my-events-form-wrap .event-submit-form label {
    font-family: 'Montserrat', sans-serif !important;
    color: #031B83 !important;
    font-weight: 700 !important;
}
/* end of 30.6.1 */

/* 30.6.2 Form helper text — navy Nunito */
.event-submit-form .form-help,
.event-submit-form .form-hint,
.event-submit-form small,
.event-submit-form .helper-text,
.my-events-form-wrap .event-submit-form p,
.my-events-form-wrap .event-submit-form small {
    color: #031B83 !important;
    font-family: 'Nunito Sans', sans-serif !important;
}
/* end of 30.6.2 */

/* 30.6.3 File input — cream brand card */
/* Native file input — restyle as cream brand card */
.event-submit-form input[type="file"],
.my-events-form-wrap .event-submit-form input[type="file"] {
    background: #fffbe6 !important;
    color: #031B83 !important;
    border: 2px solid #CC9900 !important;
    border-radius: 16px !important;
    padding: 10px 14px !important;
    font-family: 'Nunito Sans', sans-serif !important;
}
/* end of 30.6.3 */

/* 30.6.4 File input upload button (webkit) */
.event-submit-form input[type="file"]::-webkit-file-upload-button,
.my-events-form-wrap .event-submit-form input[type="file"]::-webkit-file-upload-button {
    background: #031B83 !important;
    color: #CC9900 !important;
    border: 0 none !important;
    border-radius: 10px !important;
    padding: 6px 14px !important;
    margin-right: 12px !important;
    font-family: 'Montserrat', sans-serif !important;
    font-weight: 700 !important;
    cursor: pointer;
}
/* end of 30.6.4 */

/* 30.6.5 Color input — compact branded swatch */
/* Native color input — compact branded swatch instead of full-width navy rectangle */
.event-submit-form input[type="color"],
.my-events-form-wrap .event-submit-form input[type="color"] {
    width: 64px !important;
    height: 40px !important;
    padding: 2px !important;
    border: 2px solid #CC9900 !important;
    border-radius: 12px !important;
    background: #fffbe6 !important;
    cursor: pointer;
}
/* end of 30.6.5 */

/* 30.6.6 Submission review-footer — gold-bordered note */
/* Submission review-footer — navy Montserrat so the "will be reviewed" text
   reads as a brand note not a default grey disclaimer. */
.event-submit-form .submission-footer,
.event-submit-form .submit-note,
.my-events-form-wrap .event-submit-form .submission-footer,
.my-events-form-wrap .event-submit-form > p:last-of-type {
    color: #031B83 !important;
    font-family: 'Nunito Sans', sans-serif !important;
    font-style: italic;
    background: rgba(204, 153, 0, 0.06);
    border-left: 3px solid #CC9900;
    padding: 10px 14px;
    border-radius: 0 12px 12px 0;
    margin-top: 16px;
}
/* end of 30.6.6 */
/* end of 30.6 */

/* 30.7 Account page brand violations (S62 Rob flag — ORGANISER pill, Change
        Plan, Cancel Membership, Change Password) — align with LB-023/024. */
/* 30.7.1 Tier pill per-tier tint palette */
/* 30.7.1.1 Tier pill base */
/* Account subscription tier pill — use per-tier tint palette (same rules as
   .bio-level + .member-card-level.level-*). Any ORGANISER/VENUE/etc. badge on
   the account page with class .account-tier-badge or .pmpro-level-name gets
   the per-tier treatment. */
.account-tier-badge,
.pmpro-level-name,
.pmpro_a-s-content .pmpro_level_info strong {
    font-family: 'Montserrat', sans-serif !important;
    font-weight: 700 !important;
    border-radius: 9999px !important;
    padding: 4px 12px 5px !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    align-self: center !important;
    line-height: 1 !important;
    border: 0 none !important;
    text-transform: uppercase;
    font-size: 11px;
    letter-spacing: 0.5px;
}
/* end of 30.7.1.1 */

/* 30.7.1.2 Tier pill — organiser tint */
/* D-652 25/09/2026, Rob: all tier pills cream and gold. Per-tier tint retired, replaced at
   source with the same three values as every other tier - see 42.7. */
.account-tier-badge.level-organiser,
.pmpro-level-name.level-organiser {
    background: var(--color-cream) !important;
    color: var(--color-navy) !important;
    border: 1px solid var(--color-gold) !important;
}
/* end of 30.7.1.2 */

/* 30.7.1.3 Tier pill — venue tint */
.account-tier-badge.level-venue,
.pmpro-level-name.level-venue {
    background: var(--color-cream) !important;
    color: var(--color-navy) !important;
    border: 1px solid var(--color-gold) !important;
}
/* end of 30.7.1.3 */

/* 30.7.1.4 Tier pill — premium tint */
.account-tier-badge.level-premium,
.pmpro-level-name.level-premium {
    background: var(--color-cream) !important;
    color: var(--color-navy) !important;
    border: 1px solid var(--color-gold) !important;
}
/* end of 30.7.1.4 */

/* 30.7.1.5 Tier pill — standard tint */
.account-tier-badge.level-standard,
.pmpro-level-name.level-standard {
    background: var(--color-cream) !important;
    color: var(--color-navy) !important;
    border: 1px solid var(--color-gold) !important;
}
/* end of 30.7.1.5 */

/* 30.7.1.6 Tier pill — free tint */
.account-tier-badge.level-free,
.pmpro-level-name.level-free {
    background: var(--color-cream) !important;
    color: var(--color-navy) !important;
    border: 1px solid var(--color-gold) !important;
}
/* end of 30.7.1.6 */

/* 30.7.1.7 Tier pill — dating tint */
/* D-652 25/09/2026: was missing entirely (Rule 13). Added on the same recipe as every other
   tier here, see 42.7 .tier-badge--dating. */
.account-tier-badge.level-dating,
.pmpro-level-name.level-dating {
    background: var(--color-cream) !important;
    color: var(--color-navy) !important;
    border: 1px solid var(--color-gold) !important;
}
/* end of 30.7.1.7 */
/* end of 30.7.1 */

/* 30.7.2 Account action buttons — cream/gold/navy brand button */
/* 30.7.2.1 Action button base */
/* Change Plan / Change Password / Cancel Membership buttons on account page —
   LB-023 cream/gold/navy brand button (default) instead of the retired
   gold-bg/navy-text variant. */
.pmpro_account-membership .pmpro_btn,
.pmpro_account-membership a.pmpro_btn,
.account-change-plan-btn,
.account-change-password-btn,
.pmpro_a-s-change_account_info,
.pmpro_a-s-change_password {
    background: #fffbe6 !important;
    color: #031B83 !important;
    border: 2px solid #CC9900 !important;
    border-radius: 16px !important;
    font-family: 'Montserrat', sans-serif !important;
    font-weight: 700 !important;
    padding: 10px 24px !important;
    text-decoration: none !important;
    transition: background 160ms ease, transform 120ms ease, box-shadow 160ms ease;
}
/* end of 30.7.2.1 */

/* 30.7.2.2 Action button hover */
.pmpro_account-membership .pmpro_btn:hover,
.pmpro_account-membership a.pmpro_btn:hover,
.account-change-plan-btn:hover,
.account-change-password-btn:hover {
    background: #fff5cc !important;
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.16) !important;
}
/* end of 30.7.2.2 */
/* end of 30.7.2 */

/* 30.7.3 Cancel Membership link — navy underlined
   S68 T492-F14 (2026-04-18): selector corrected. Live /account/ page emits
   `.account-actions .account-btn-link` for this link (custom uksocials
   template, not PMPro's default `.pmpro_actionlink-cancel`). Previous
   selectors kept as fallback for PMPro default layouts elsewhere. */
/* 30.7.3.1 Cancel link base */
.pmpro_account-membership .pmpro_actionlink-cancel,
.account-cancel-membership,
.account-actions .account-btn-link {
    color: #031B83 !important;
    font-family: 'Montserrat', sans-serif !important;
    font-weight: 700 !important;
    text-decoration: underline;
}
/* end of 30.7.3.1 */

/* 30.7.3.2 Cancel link hover */
.pmpro_account-membership .pmpro_actionlink-cancel:hover,
.account-cancel-membership:hover,
.account-actions .account-btn-link:hover {
    color: #CC9900 !important;
}
/* end of 30.7.3.2 */
/* end of 30.7.3 */

/* 30.7.8 S68 Phase 9 Save 9b F5 — /settings/profile/ visibility select
   SW3 radius alignment. Was 8px. D090/SW3 spec is 16px. */
.bp-user #item-body select[id*="field_"][id*="visibility"],
.bp-user #item-body .field-visibility-settings select,
.bp-user #item-body form.standard-form select {
    border-radius: 16px !important;
    padding: 6px 12px !important;
}

/* 30.7.7 S68 Phase 9 Save 9a F8 — BP `.count` bubble colour.
   Was bg rgba(178,178,178,0.2) grey + navy text (default BP theme).
   Align to D055: gold bg + navy text, matching `.invite-tab-count` /
   `.mi-count` pattern shipped in S68-001/S68-003. Affects all sidenav
   count chips (Messages 9, Notifications 10, Event Invites N, etc.). */
#item-body a .count,
.dashboard-sidenav .count,
.sidenav-item .count,
.bp-user .item-nav .count {
    background: #CC9900 !important;
    color: #031B83 !important;
    font-family: 'Nunito Sans', sans-serif !important;
    font-weight: 700 !important;
    border-radius: 9999px !important;
    padding: 2px 8px !important;
}

/* 30.7.6 S68 T492 SW3 remainder — `.accordion-card` on /attendance/.
   Was transparent bg + transparent border + 9px radius + no shadow. Apply
   SW3 card spec: white bg, navy@10% border, 16px radius, shadow-sm. */
.accordion-card,
.attendance-profile-section .accordion-card,
.accordion-card.accordion-validation {
    background: #FFFFFF !important;
    border: 1px solid rgba(3,27,131,0.1) !important;
    border-radius: 16px !important;
    box-shadow: 0 2px 6px rgba(3,27,131,0.06) !important;
    padding: 16px 18px !important;
    margin-bottom: 12px;
}

/* 30.7.5 S68 T492 D7/D8 — /messages/compose/ form inputs (SW3 card-spec
   remainder). BP's default BP 11 markup emits 1px solid #E0E0E0 border +
   8-9px radius on send-to / subject / message_content. Align to SW3 spec:
   navy@10% border, 16px radius, gold hairline on focus per D055 accent. */
/* 30.7.5.1 Compose inputs base */
#send_message_form input[type="text"],
#send_message_form input[type="email"],
#send_message_form textarea,
#send_message_form .send-to-input,
form[name="send_message"] input[type="text"],
form[name="send_message"] textarea {
    border: 1px solid rgba(3,27,131,0.1) !important;
    border-radius: 16px !important;
    padding: 10px 14px !important;
    font-family: 'Nunito Sans', sans-serif !important;
    color: #031B83 !important;
    background: #FFFFFF !important;
}
/* end of 30.7.5.1 */

/* 30.7.5.2 Compose inputs focus */
html[data-nav="kbd"] #send_message_form input:focus,
html[data-nav="kbd"] #send_message_form textarea:focus,
html[data-nav="kbd"] form[name="send_message"] input:focus,
html[data-nav="kbd"] form[name="send_message"] textarea:focus {
    border-color: #CC9900 !important;
    outline: none !important;
    box-shadow: 0 0 0 2px rgba(204,153,0,0.15);
}
/* end of 30.7.5.2 */
/* end of 30.7.5 */

/* 30.7.4 S68 T492-F17 — BP subnav font drift. Default parent theme serves
   Muli on member subnavs; brand standard is Montserrat (BRAND_GUIDE §3).
   Selector covers both patterns: `#subnav` (settings-style) + `.item-subnav`
   (messages / event-invites-style). Does NOT change size/weight — just font
   family so the D055 active-pill rules remain untouched. */
.bp-user #subnav a,
.bp-user .item-subnav a,
.bp-user .item-list-tabs a {
    font-family: 'Montserrat', sans-serif !important;
}


/* 30.8 Cascade-winner overrides — raise specificity on two S63 Phase 1c items
        that didn't land on first upload (T455 miss retrospective):
        - .profile-widget border was still inheriting grey #e8e8e8 (the new
          rule at profile-editor.css §820 had equal specificity and a later
          rule somewhere was winning); bump with body-scoped override.
        - .bio-level font was rendering Nunito Sans because the
          `.profile-grid-public .profile-widget *` body-text rule at
          profile-editor.css §837 had higher specificity (0,2,1) than
          `.bio-level` (0,1,0). Force Montserrat on all tier pills.
*/
/* 30.8.1 .profile-widget border — gold @35% override */
body.bp-user .profile-grid-public .profile-widget,
body .profile-grid-public .profile-widget {
    /* S227 15/09/26, item 218. Rob: "the profile on the public-facing page should be white
       with a gold border - They should be the same." This rule was setting a 1px 35 percent
       gold while the identical widget on the customise page carries S199's 2px solid
       #CC9900, which is the rule he asked for in the words "It should be the same border as
       the workspace itself". MEASURED on his own profile: 1px rgba(204,153,0,0.35) public
       against 2px rgb(204,153,0) on customise. The two values are corrected here rather
       than a second rule being added; the per-widget colour picker is (0,4,1) and still
       outranks this, so a member's own chosen border colour is untouched. */
    border-color: #CC9900 !important;
    border-width: 2px !important;
    border-style: solid !important;
}
/* end of 30.8.1 */

/* 30.8.2 .bio-level + tier badges — Montserrat */
body .profile-grid-public .bio-level,
body .profile-grid-public .badge-free,
body .profile-grid-public .badge-standard,
body .profile-grid-public .badge-premium,
body .profile-grid-public .badge-organiser,
body .profile-grid-public .badge-venue,
body .profile-grid-public .badge-admin,
body .bio-level,
body span.bio-level {
    font-family: 'Montserrat', sans-serif !important;
}
/* end of 30.8.2 */
/* end of 30.8 */

/* end of 30 */

/* ============================================================================
   31. S74 Phase 11a-1 — /events/ public page fixes (Rob 2026-04-20)
   - Badge + date pill stacked vertically, centered in card image area
   - All card body content centered (title, Free, venue, excerpt, footer)
   - Page H1 centered on public pages (via .svq-page-header wrapper)
   - Featured grid counts: 1 col at <=480, 2 cols 481-1023, 4 cols 1024-1279
     (1280+ keeps existing auto-fill minmax behaviour)
   Scoped via .events-page-wrapper / .event-card to avoid blast radius.
   ============================================================================ */

/* 31.1 Page title centered on /events/ public page */
/* 31.1.1 Header wrapper — centre */
body:has(.events-page-wrapper) .svq-page-header,
body:has(.events-page-wrapper) .svq-page-header-inner {
    text-align: center !important;
}
/* end of 31.1.1 */

/* 31.1.2 Header titles — block centred */
body:has(.events-page-wrapper) .svq-page-header .entry-title,
body:has(.events-page-wrapper) .svq-page-header .page-title,
body:has(.events-page-wrapper) .svq-page-header h1,
body:has(.events-page-wrapper) .svq-page-header h2 {
    text-align: center !important;
    display: block !important;
    width: 100% !important;
    margin-left: auto !important;
    margin-right: auto !important;
}
/* end of 31.1.2 */
/* end of 31.1 */

/* 31.2 Event card body content — centered per Rob's independent-content rule */
/* 31.2.1 Body/title/excerpt — centre */
.events-page-wrapper .event-card-body,
.events-page-wrapper .event-card-title,
.events-page-wrapper .event-card-excerpt {
    text-align: center !important;
}
/* end of 31.2.1 */

/* 31.2.2 Footer — wrap centre */
.events-page-wrapper .event-card-footer {
    justify-content: center !important;
    flex-wrap: wrap !important;
}
/* end of 31.2.2 */

/* 31.2.3 Organiser — full-width centred */
/* .event-card-organiser margin-left:auto (event-system.php:5125) pushes it to the
   right end when flex row. Override so it centers in the flex-wrap footer row. */
.events-page-wrapper .event-card-organiser {
    margin-left: 0 !important;
    width: 100% !important;
    text-align: center !important;
}
/* end of 31.2.3 */
/* end of 31.2 */

/* 31.3 Banner = image territory only. Badge (category label) stays on banner
   top-centered. Date pill moves OFF the banner and flows naturally in the
   white body below (inside .event-card-meta, per event-system.php:4759).
   Banner height unified at 160px whether image present or not, so colour-block
   fallback looks substantial and never squashed. Per Rob 2026-04-20: "the
   date and stuff can't be on that banner. Because that's where people put
   their images. It needs to be in the white box underneath with the rest of
   the content." */
/* 31.3.1 Banner image — fixed 160px height */
.events-page-wrapper .event-card .event-card-image,
.events-page-wrapper .event-card .event-card-image.event-card-no-image {
    min-height: 160px !important;
    height: 160px !important;
    position: relative !important;
    display: block !important;
}
/* end of 31.3.1 */

/* 31.3.2 Banner badge — top-centred absolute */
.events-page-wrapper .event-card .event-card-image .event-card-badge,
.events-page-wrapper .event-card .event-card-image.event-card-no-image .event-card-badge {
    position: absolute !important;
    top: 14px !important;
    left: 50% !important;
    right: auto !important;
    transform: translateX(-50%) !important;
    white-space: nowrap !important;
}

/* 31.3.2a S168 — the centred badge COLLIDES with the right-hand pills, so it stops being centred
   when one is present.
   MEASURED on the live anonymous /events/ archive at 1280 (card image 276px wide):
       badge      x  90->186   y 14->45   "Food & Drink"   (31px tall, not the ~26 the offsets assume)
       agePill    x 218->266   y 10->40   "18+"
       noScreens  x 150->266   y 42->75   "No screens"
   The badge is 31px tall, so it ends at y45 while the no-screens pill starts at y42 - a real 36x3px
   overlap - and horizontally the pill reaches back to x150 against the badge's x186.
   ⚠️ Nudging `top` only fixes one combination. §35.1's own `:not(:has(.event-age-pill))` case puts
   the no-screens pill at top:10, which overlaps the badge far MORE. The structural cause is that the
   badge is centred while every other pill is right-aligned, so on a 276px card they meet in the
   middle. Five overlaps were measured across the visible cards.
   So: keep the designed centred badge wherever nothing can collide with it, and left-align it only on
   the cards that carry a right-hand pill. `:has()` is already relied on by §35.1 in this file. */
.events-page-wrapper .event-card .event-card-image:has(.event-age-pill) .event-card-badge,
.events-page-wrapper .event-card .event-card-image:has(.event-no-screens-pill) .event-card-badge {
    left: 14px !important;
    transform: none !important;
}
/* end of 31.3.2a */
/* end of 31.3.2 */

/* 31.3.3 Date pill — reset absolute, flow inline */
/* Date pill — reset any absolute positioning it inherits from earlier rules
   (page-polish.css:80 sets top:12/right:12 absolute; §28.8 sets gold border;
   §30.2 sets colour/font). Force in-flow in .event-card-meta so it renders
   in the card body below the title, centred under §31.2 text-align:center
   on .event-card-body. */
.events-page-wrapper .event-card .event-card-date,
.events-page-wrapper .events-featured-scroll .event-card-date,
.events-page-wrapper .events-grid .event-card-date {
    position: static !important;
    top: auto !important;
    left: auto !important;
    right: auto !important;
    transform: none !important;
    display: inline-block !important;
    margin: 0 auto 8px !important;
    white-space: nowrap !important;
    /* Per Rob 2026-04-20: pill sizes naturally to content + padding. No width
       cap. Longest date the backend emits is "Wed 22nd September - 11:30pm". */
    max-width: none !important;
    width: auto !important;
}
/* end of 31.3.3 */

/* 31.3.4 Card-meta — centre */
/* .event-card-meta wraps date + venue — center so date pill and venue
   address stack centred under the card title. */
.events-page-wrapper .event-card .event-card-meta {
    align-items: center !important;
    text-align: center !important;
}
/* end of 31.3.4 */
/* end of 31.3 */

/* 31.3.5 Calendar emoji on date pill — the emoji's glyph renders wider than
   its inline-character footprint in some browser/font combos, so even a
   margin-right of 6px can still visually overlap the "Wed" text. Wrap the
   emoji in a fixed-width inline-block so its horizontal footprint is locked
   independent of glyph rendering. 22px width covers all emoji renderings. */
.events-page-wrapper .event-card-date::before {
    display: inline-block !important;
    width: 22px !important;
    text-align: center !important;
    margin-right: 4px !important;
    vertical-align: middle !important;
}

/* 31.4 Featured grid column counts per browser width (Rob 2026-04-20)
   - 360/mobile up to 480: 1 col
   - 481 to 1023: 2 cols (covers 768/810/1024's lower boundary)
   - 1024 to 1279: 4 cols
   - 1280+: keep existing auto-fill minmax(280px, 1fr) */
/* 31.4.1 Mobile <=480 — single col */
@media (max-width: 480px) {
    .events-page-wrapper .events-featured-scroll,
    .events-page-wrapper .events-grid {
        grid-template-columns: minmax(0, 1fr) !important;
        gap: 16px !important;
    }
}
/* end of 31.4.1 */

/* 31.4.2 Constrained-grid cards — shrink below min-content */
/* S77 Rob: stale 481-1279 2-col rule removed — it was winning at 1024 over
   the section 30.1 breakpoints (1900+=4, 1000-1899=3, 790-999=2, <790=1)
   because of source-order + !important. Columns now owned solely by §30.1. */
/* Cards inside constrained grids must be allowed to shrink below min-content
   (default grid item min-width is auto = min-content, which breaks 4-col at
   1024). */
.events-page-wrapper .events-featured-scroll .event-card,
.events-page-wrapper .events-grid .event-card {
    min-width: 0 !important;
}
/* end of 31.4.2 */
/* end of 31.4 */

/* end of 31 */

/* ============================================================================
   32. S74-003 /events/ round-2 fixes (Rob 2026-04-20)
   - Filter selects de-pilled (were styled as pill-buttons, should be selects)
   - 810/768 filter layout → 2×2 grid (matching 1024's pattern)
   - Search + Reset button row centred
   - Card title fixed 2-line min-height with vertical centre — date Y always
     matches across cards regardless of title line count
   - Logo forced visible at 1024 + 810 (Elementor responsive-hide override)
   - 810 → hide desktop nav, force hamburger (matches 768/360 mobile header)
   ============================================================================ */

/* 32.1 De-pill the filter selects — §30.4 was styling them with 16px radius +
   2px gold border which matched button chrome, making them read as buttons.
   Selects should read as selects: gold border (stronger than before per
   S76-006 Rob — 1px/60% was too weak), smaller radius, visible dropdown
   arrow on the right. */
/* 32.1.1 Filter inputs/selects — gold border 8px radius */
.events-page-wrapper .events-filter-row select,
.events-page-wrapper .events-filter-section select,
.events-page-wrapper .events-filter-row input[type="text"],
.events-page-wrapper .events-filter-row input[type="search"],
.events-page-wrapper .events-filter-section input[type="text"],
.events-page-wrapper .events-filter-section input[type="search"] {
    border: 2px solid #CC9900 !important;
    border-radius: 8px !important;
    padding: 8px 14px !important;
    background-color: #ffffff !important;
}
/* end of 32.1.1 */

/* 32.1.2 Filter selects — SVG chevron arrow */
.events-page-wrapper .events-filter-row select,
.events-page-wrapper .events-filter-section select {
    /* Native dropdown arrow via SVG — navy chevron on right */
    appearance: none !important;
    -webkit-appearance: none !important;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path fill='%23031B83' d='M6 8L0 0h12z'/></svg>") !important;
    background-repeat: no-repeat !important;
    background-position: right 12px center !important;
    background-size: 12px 8px !important;
    padding-right: 32px !important;
}
/* end of 32.1.2 */
/* end of 32.1 */

/* 32.2 Search/Reset button row — centre as a unit. Reset should not be a plain
   left-aligned text link floating at the right. Keep them on same visual line,
   both centred together. */
/* 32.2.1 Filter row secondary — flex centre with gap */
.events-page-wrapper .events-filter-row-secondary,
.events-page-wrapper .events-filter-form .events-filter-row:last-child,
.events-page-wrapper .events-filter-actions {
    display: flex !important;
    justify-content: center !important;
    align-items: center !important;
    gap: 16px !important;
    flex-wrap: wrap !important;
}
/* end of 32.2.1 */

/* 32.2.2 Reset link — Montserrat navy underlined */
.events-page-wrapper .events-filter-reset {
    font-family: 'Montserrat', sans-serif !important;
    color: #031B83 !important;
    text-decoration: underline !important;
    font-weight: 600 !important;
}
/* end of 32.2.2 */

/* 32.2.3 Reset link hover */
.events-page-wrapper .events-filter-reset:hover {
    color: #CC9900 !important;
}
/* end of 32.2.3 */
/* end of 32.2 */

/* 32.3 Filter layout. S219 REWRITE (Rob 10/09/26, via Loose ends 04: "That's not what it actually looks like
   right now... I've given this to Opus to sort out"). The row was flex at 1280 (search and two dropdowns on one
   line, the other two stretched across a second line) and a 2 x 2 grid below it with the fifth control centred
   on its own. It is now ONE grid at every width: the search box across the top, and the dropdowns (the events
   .ev-dd controls, or the venue and organiser pages' selects) the same width beneath it, four across from 1024,
   two by two from 601, one column on a phone at the row's full width. The old orphan-centring rule is gone
   because there is no orphan any more. The .ev-dd minimum from the page's inline CSS gives way here, so four
   controls fit the 713px row: each is 169px, which leaves the 101px label box All Age Groups needs. */
.events-page-wrapper .events-filter-row {
    display: grid !important;
    grid-template-columns: 1fr !important;
    gap: 12px !important;
    width: 100% !important;
    flex-direction: unset !important;
    align-items: center !important;
}
@media (min-width: 601px) {
    .events-page-wrapper .events-filter-row { grid-template-columns: repeat(2, 1fr) !important; }
}
/* Four across only from 1280: at 1024 the row is 424px wide, too narrow for four labels. */
@media (min-width: 1280px) {
    .events-page-wrapper .events-filter-row { grid-template-columns: repeat(4, 1fr) !important; }
}
/* 28px each side (the chevron sits 14px in and is 15px wide) gives the 169px control a 109px label box, so
   All Age Groups (106px) shows in full; still symmetric, so every label stays on its control's centre. */
.events-page-wrapper .events-filter-row .ev-dd__btn {
    padding-left: 28px;
    padding-right: 28px;
}
/* On a phone the section and the form both padded the row, leaving it 186px of a 390 screen. */
@media (max-width: 600px) {
    .events-page-wrapper .events-filter-section .events-filter-form { padding-left: 0 !important; padding-right: 0 !important; width: 100% !important; max-width: none !important; }
}
.events-page-wrapper .events-filter-row > .events-search-input {
    grid-column: 1 / -1 !important;
    width: 100% !important;
    min-width: 0 !important;
    flex: unset !important;
}
.events-page-wrapper .events-filter-row > .ev-dd,
.events-page-wrapper .events-filter-row > .events-filter-select {
    width: 100% !important;
    min-width: 0 !important;
    max-width: none !important;
    flex: unset !important;
}

/* 32.4 Card title — fixed 2-line height, vertically centred.
   1-line titles get vertical centering within the 2-line slot so date pill
   Y-position is identical to 2-line-title cards. Uses line-height 1.3 × 16px
   font = ~21px per line × 2 = 42px min-height. */
.events-page-wrapper .event-card .event-card-title {
    min-height: calc(1.3em * 2) !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    margin: 0 0 8px !important;
    line-height: 1.3 !important;
}

/* 32.7 Section headings (Coming Up / Later This Month / This Weekend etc.) —
   `.events-period-title` at event-system.php:5104 had no text-align. D105
   centred independent content. */
.events-page-wrapper .events-period-title,
.events-page-wrapper .events-period-section .events-period-title {
    text-align: center !important;
    /* S215 (EV-01): the featured-event title spacing, copied exactly. 28.1.2 gives
       .events-section-title padding-bottom 20 and margin-bottom 29, and 28.1.3 gives
       the block below it margin-top 14. */
    padding-bottom: 20px !important;
    margin-bottom: 29px !important;
    /* S217 (EV-01, Rob 09/09/26): the featured heading carries a 2px gold rule under it and
       these four carried none, so the page had two kinds of heading. Same rule, same colour. */
    border-bottom: 2px solid #CC9900 !important;
}
.events-page-wrapper .events-period-section .events-grid {
    margin-top: 14px !important;
}

/* 32.8 Reset — a matching secondary button stacked below Search. */
.events-page-wrapper #events-filter-form .events-filter-button,
.events-page-wrapper #events-filter-form .events-filter-reset {
    width: 100px !important;
    min-width: 100px !important;
    max-width: 100px !important;
    height: 46px !important;
    box-sizing: border-box !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    padding: 0 !important;
}
/* 32.8.1 Reset button base style — cream, gold and navy secondary action (D-640).
   R3-39 (24/09/2026), Rob on the organisers page's "Show anywhere": "no side padding, no cream
   background... standard button with the same padding as Search above it." This selector has no
   #events-filter-form ancestor requirement, so the /events/ page's own 100px/no-padding pill
   (32.8 above, id-gated to that one form) is untouched; only organisers/venues/locations, whose
   forms carry a different id, ever fell through to this rule's own padding (none) and background
   (was #FFFFFF). Padding matches .events-filter-button's own live 10px 24px (30.3.1). */
.events-page-wrapper .events-filter-reset {
    background: var(--color-cream, #FFFBE6) !important;
    color: #031B83 !important;
    border: 2px solid #CC9900 !important;
    border-radius: 10px !important;
    font-family: 'Montserrat', sans-serif !important;
    font-size: 14px !important;
    font-weight: 700 !important;
    line-height: 1 !important;
    text-decoration: none !important;
    box-shadow: var(--shadow-gold-hover) !important;
    margin: 0 !important;
    padding: 10px 24px !important;
}
/* end of 32.8.1 */
/* 32.8.2 Filter row containers — flex column, centre, 18px gap */
.events-page-wrapper .events-filter-row-secondary,
.events-page-wrapper .events-filter-form .events-filter-row:last-child,
.events-page-wrapper .events-filter-actions {
    display: flex !important;
    flex-direction: column !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 18px !important;
    margin-top: 0 !important;
}
/* end of 32.8.2 */
/* 32.8.3 Filter form container — flex column, 18px padding + gap (symmetric around Search) */
/* S76-006 Rob: the gaps should be symmetric AROUND Search as well — container
   padding (top+bottom) == gap between filter inputs and Search == gap between
   Search and Reset == gap between Reset and bottom. 18px everywhere. */
.events-page-wrapper .events-filter-form {
    display: flex !important;
    flex-direction: column !important;
    align-items: center !important;
    gap: 18px !important;
    padding: 18px !important;
}
/* end of 32.8.3 */
/* 32.8.4 Reset button hover — the standard darker cream. */
.events-page-wrapper .events-filter-reset:hover {
    background: #FFF5CC !important;
    color: #031B83 !important;
}
/* end of 32.8.4 */
/* end of 32.8 */

/* 32.9 Hide Seeko breadcrumb globally with !important. style.css:317 has
   `.svq-breadcrumb { display: none; }` but theme-static.min.css loads after
   with `.svq-breadcrumb { display: flex; }` which wins on equal specificity.
   Override with !important. */
body .svq-breadcrumb,
body ol.svq-breadcrumb,
body .svq-page-header .svq-breadcrumb {
    display: none !important;
}

/* 32.10 Centre page title site-wide per D105. */
body .svq-page-header,
body .svq-page-header .entry-title,
body .svq-page-header .page-title,
body .svq-page-header h1 {
    text-align: center !important;
}

/* 32.11 /members/ — at 360–768 hide the "Order By:" label and centre the
   dropdown. BP applies display:inline-flex !important on
   `body.directory.members #buddypress li#members-order-select > label` —
   match that specificity exactly to beat it. Rob 2026-04-21. */
@media (max-width: 768px) {
    /* ID doubled to out-specify Seeko's same-specificity rule on this label */
    body.directory.members #buddypress#buddypress li#members-order-select > label {
        display: none !important;
    }
    body.directory.members #buddypress#buddypress li#members-order-select {
        justify-content: center !important;
        text-align: center !important;
    }
}

/* 32.12 S77 Rob: below the editor's own cut-off the Profile/Customise preview-nav
   cluster and the whole device-selector are hidden, and in the band above it only the
   tablet + mobile preview buttons make sense. At 1024+ the full set is shown.
   S215 (CUST-32): the cut-off was 810 here and 768 in the redirect (profile-system.php,
   the innerWidth < 768 guard), so between 768 and 809 a member sat in the editor with no
   preview-size control at all. Both numbers are now 768, which is the tablet breakpoint
   the platform already uses everywhere else. */
/* 32.12.1 RETIRED S217 09/09/2026. It hid the preview nav and the whole device selector below
   768, which under Rob's ruling that customise must work on an iPad and a phone is exactly the
   control a phone needs: the Loose ends lane's ladder now offers the viewport's own size and
   everything below it, so at 390 a member gets Mobile. Deleting the rule rather than narrowing
   it, because there is no width at which the control should be absent now. */

/* 32.12.2 768-1023 - hide widescreen + desktop device buttons (S215, was 810-1023) */
@media (min-width: 768px) and (max-width: 1023px) {
    .device-selector .device-btn[data-device="widescreen"],
    .device-selector .device-btn[data-device="desktop"] {
        display: none !important;
    }
}
/* end of 32.12.2 */
/* end of 32.12 */

/* 32.14 S77 Rob item 9: venue/organiser card footer uses CSS grid with
   FIXED rows. Each row holds a specific content type and keeps its Y
   position even if the content is missing \u2014 so the Show Interest button is
   always in the same vertical spot regardless of whether the card has an
   address, price, or event-count. */
/* 32.14.1 Footer \u2014 3-row grid */
.events-grid .event-card .event-card-footer {
    display: grid !important;
    grid-template-rows: 22px 22px 38px !important;
    row-gap: 6px !important;
    align-items: center !important;
    justify-items: center !important;
    margin-top: auto !important;
    padding-top: 10px !important;
    width: 100% !important;
}
/* end of 32.14.1 */

/* 32.14.2 Footer venue \u2014 row 1 */
.events-grid .event-card .event-card-footer .event-card-venue {
    grid-row: 1 !important;
    margin: 0 !important;
    text-align: center !important;
    align-self: center !important;
}
/* end of 32.14.2 */

/* 32.14.3 Footer price \u2014 row 2 */
.events-grid .event-card .event-card-footer .event-card-price {
    grid-row: 2 !important;
    margin: 0 !important;
    align-self: center !important;
}
/* end of 32.14.3 */

/* 32.14.4 Footer wishlist button \u2014 row 3 */
.events-grid .event-card .event-card-footer .wishlist-button {
    grid-row: 3 !important;
    margin: 0 auto !important;
    align-self: center !important;
}
/* end of 32.14.4 */

/* 32.14.5 S215 (EV-15 / EV-02): the venue and organiser card footers emit up to SIX children
   and 32.14.1 only declares three rows, so postcode, event-count and Report were auto-placed
   into whatever cell was free. That is why the control order changed from card to card and why
   the last control landed outside the card. The standing rule is permanent rows that hold
   position, an empty row staying empty, and the card growing taller if it needs to (Rob, his
   April list, item 6). Scoped to the two directory grids so the /events/ event card, whose
   footer holds a different set of children, is untouched. */
.events-grid.venue-directory-grid .event-card .event-card-footer,
.events-grid.organiser-directory-grid .event-card .event-card-footer {
    grid-template-rows: 22px 22px 22px 22px 38px 38px !important;
}
.events-grid.venue-directory-grid .event-card .event-card-footer .event-card-venue,
.events-grid.organiser-directory-grid .event-card .event-card-footer .event-card-venue {
    grid-row: 1 !important;
}
.events-grid.venue-directory-grid .event-card .event-card-footer .event-card-postcode,
.events-grid.organiser-directory-grid .event-card .event-card-footer .event-card-postcode {
    grid-row: 2 !important;
    margin: 0 !important;
    align-self: center !important;
}
.events-grid.venue-directory-grid .event-card .event-card-footer span.event-card-price,
.events-grid.organiser-directory-grid .event-card .event-card-footer span.event-card-price {
    grid-row: 3 !important;
}
.events-grid.venue-directory-grid .event-card .event-card-footer a.event-card-price,
.events-grid.organiser-directory-grid .event-card .event-card-footer a.event-card-price {
    grid-row: 4 !important;
}
.events-grid.venue-directory-grid .event-card .event-card-footer .wishlist-button,
.events-grid.organiser-directory-grid .event-card .event-card-footer .organiser-card-wishlist {
    grid-row: 5 !important;
    margin: 0 auto !important;
    align-self: center !important;
}
.events-grid.venue-directory-grid .event-card .event-card-footer .event-card-report-wrap,
.events-grid.organiser-directory-grid .event-card .event-card-footer .organiser-card-report {
    grid-row: 6 !important;
    margin: 0 auto !important;
    align-self: center !important;
}
/* end of 32.14.5 */
/* end of 32.14 */

/* 32.13 S77 Rob items 14/15: Venue + organiser cards carry a sigil (logo)
   overlay on top of the main image. Circular 56x56 with gold border, docked
   bottom-left. Mirrors the member-card sigil treatment so venues,
   organisers, and members read as the same card family. */
/* 32.13.1 Image with sigil — relative positioning */
.event-card-image--has-sigil {
    position: relative !important;
}
/* end of 32.13.1 */

/* 32.13.2 Sigil overlay — circular gold-bordered */
/* S77 Rob item 7: sigil sits ON the banner image (not spilling below) and
   is 20% bigger than the previous docked version. 53x53 circle, bottom-left
   with 8px inset inside the banner. */
.event-card-sigil {
    position: absolute !important;
    left: 10px;
    bottom: 8px;
    width: 53px;
    height: 53px;
    border-radius: 50%;
    background: #031B83;
    border: 2px solid #CC9900;
    overflow: hidden;
    box-shadow: 0 2px 8px rgba(3, 27, 131, 0.18);
    z-index: 5;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #CC9900;
}
/* end of 32.13.2 */

/* 32.13.3 Sigil img — fill cover */
/* S217 09/09/2026 (EV-25): the Gravatar fallback is now a TRANSPARENT image rather than the
   grey silhouette, so whatever is painted behind it is what a member without a photo sees.
   BRAND_GUIDE 18 names the Default Sigil gradient for exactly this case. */
.event-card-sigil img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    /* S219 (CUST-124): the gold Account person on the placeholder, as on every sigil surface */
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='3.75 4.19 16.5 17.8'%3E%3Cpath d='M4.6 21.14c0-4.1 3.3-6.6 7.4-6.6s7.4 2.5 7.4 6.6z' fill='%23CC9900'/%3E%3Ccircle cx='12' cy='8.74' r='3.7' fill='%23CC9900'/%3E%3C/svg%3E") center 50% / 46% no-repeat, linear-gradient(145deg, #041D88, #0A2A9E);
}
/* end of 32.13.3 */

/* 32.13.4 Sigil dashicon */
.event-card-sigil .dashicons {
    font-size: 28px;
    width: 28px;
    height: 28px;
    line-height: 1;
    color: #CC9900;
}
/* end of 32.13.4 */

/* 32.13.5 Fallback tile — no image */
/* S77 Rob: sigil now sits ON banner, no overflow into body so no extra
   padding-top needed. */
/* Fallback tile when no image is available. */
.event-card-image-fallback {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    background: linear-gradient(135deg, #031B83 0%, #0a2ea8 100%);
    color: #CC9900;
}
/* end of 32.13.5 */

/* 32.13.6 Fallback dashicon */
.event-card-image-fallback .dashicons {
    font-size: 48px;
    width: 48px;
    height: 48px;
}
/* end of 32.13.6 */
/* end of 32.13 */

/* end of 32 */


/* ============================================================================
   33. SECTION: Age-group pill + age-restriction notice (S84 — A4 / D128)
   Cream pill (LB-023) used on event cards (top-right of image, opposite
   the category badge), in the detail page info row, and inside the RSVP
   age-restriction notice. Mixed events render no pill — that's the
   default no-restriction state.
   ============================================================================ */

/* 33.1 Pill on event card image (top-right) */
.event-card-image .event-age-pill {
    position: absolute;
    top: 10px;
    right: 10px;
    background: #FFFBE6;
    color: #031B83;
    border: 2px solid #CC9900;
    border-radius: 9999px;
    padding: 4px 12px;
    font-family: Montserrat, sans-serif;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);
    z-index: 2;
}
/* end of 33.1 */

/* 33.2 Pill on event detail info-row (inline next to label) */
.single-event-info-row .event-age-pill {
    display: inline-block;
    margin-left: 8px;
    background: #FFFBE6;
    color: #031B83;
    border: 2px solid #CC9900;
    border-radius: 9999px;
    padding: 2px 10px;
    font-family: Montserrat, sans-serif;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
/* end of 33.2 */

/* 33.3 Age-restricted RSVP notice (replaces RSVP button when user fails the gate) */
.event-age-restricted-notice {
    background: #FFFBE6;
    border: 2px solid #CC9900;
    border-radius: 12px;
    padding: 18px 22px;
    color: #031B83;
    font-family: 'Nunito Sans', sans-serif;
    text-align: left;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.10);
}
/* TKT-1 (S238, Rob, the 28th of September 2026: "the text in the cream box is not centred"). Inside the ticket card
   everything else is centred (the price, the places line, the notices above, the terms below), so the cream notice
   is too. The same notice printed as the page's cancelled banner, under the breadcrumbs, is outside the card and
   keeps the alignment above. */
.event-aside-card .event-age-restricted-notice {
    text-align: center;
}
.event-age-restricted-notice p {
    margin: 0 0 8px;
    line-height: 1.5;
}
.event-age-restricted-notice p:last-child {
    margin-bottom: 0;
}
.event-age-restricted-notice strong {
    font-family: Montserrat, sans-serif;
    font-weight: 700;
}
.event-age-restricted-notice a {
    color: #CC9900;
    text-decoration: underline;
}
.event-age-restricted-notice a:hover {
    color: #B38800;
}
/* end of 33.3 */

/* end of 33 */


/* ============================================================================
   34. SECTION: Report button + modal + toast (S84 — A5 / D130)
   Single "Report" button hooked into every UGC surface (photos, BP messages,
   public profile footer, event/venue cards + detail pages, organiser cards).
   Click → shared modal → AJAX submit → confirmation toast. Reporter sees
   "Reported ✓" state on surfaces they've already reported (dedupe).
   ============================================================================ */

/* 34.1 The Report button — visual rules retired S100 (25/05/26).
   Now uses class="uks-report-btn btn-dashboard". All visual styling owned by
   .btn-dashboard in §43.
   S220 14/09/2026: THE DONE STATE WAS OFF BRAND AND IT WAS THE ONLY THING ON IT.
   Rob, seeing it: "this reported is being rebranded, right? Not left grey like
   that?" It was #DDD on #999 with #555 text: three hardcoded greys, all three of
   them on BRAND_GUIDE section 1.6.1's banned list, which is the rule that took
   grey off the rest of the platform. It now speaks the platform's own confirmed
   language, the same light green the Interested control and the ticket chip use
   (BRAND_GUIDE 9.2, .btn-option--select.active), so a member reads "we have it"
   rather than "this is broken". It is still not clickable: no shadow, no hover
   move, default cursor, and the button stays disabled in the markup. */
/* The selector carries three classes on purpose. 43.2's .btn-dashboard:disabled is two classes
   deep and also !important, so it was beating the one-class rule that used to live here: the greys
   below were DEAD CODE and what Rob was actually looking at was the platform's disabled treatment,
   navy at 6 percent. This outranks it without touching the shared disabled rule, which every other
   disabled button on the platform still needs. */
.uks-report-btn.uks-report-btn-done,
.uks-report-btn.uks-report-btn-done:disabled,
.uks-report-btn.uks-report-btn-done:hover {
    /* S220, Rob's second word on it: "I think maybe the reported button should be red, not green."
       Green said "well done"; a report is not a success, it is a flag raised. This is the brand
       error red as a PALE WASH with a darker border and text, which is the shape he ruled for the
       Decline button on 10/09 ("Stays red, but make sure it's the light background and darker
       border and text, not like a block of red"). */
    background: rgba(196, 28, 28, 0.06) !important;
    color: #C41C1C !important;
    border-color: #C41C1C !important;
    box-shadow: none !important;
    transform: none !important;
    cursor: default !important;
    opacity: 1 !important;
    /* The tick is absolutely positioned after the word. Its 13px ink plus the 6px label gap
       needs a further 15px clear run to the button edge: 13 + 6 + 15 = 34px on the right.
       S232 21/09/2026, Rob: "the gaps on either end from ink to ink should be 15px... merge the
       two states so that the furthest right-side ink of the tick is 15px from the border." The
       two ends were 34.875px and 15.125px, measured from the painted pixels at deviceScaleFactor
       8 on cold_prem19's profile, because the equal 34px kept the WORD centred and left the tick
       to hang into its own room. The ink run is what is centred now: the left padding is the
       15px clear run less the R's own 0.875px left side bearing, so the first letter's ink and
       the tick's last ink each stand 15px off the inner border. MEASURED AFTER: 15.125px and
       15.000px, the 0.125px being one device pixel of the button's own half-pixel position.
       The word to tick gap is untouched: it is the platform's shared 6px on
       .btn-icon-fix-icon--trail, which paints a 9px ink gap here and on Interested alike. */
    padding-left: 14.125px !important;
    padding-right: 34px !important;
}
/* end of 34.1 */

/* 34.2 Surface placement variations
   Gallery photos (overlay on each photo) */
.profile-gallery-item { position: relative; }
.profile-gallery-report-wrap {
    position: absolute;
    bottom: 8px;
    right: 8px;
    z-index: 2;
}
/* Event card / venue card / organiser card — inline with the footer row */
.event-card-report-wrap { display: inline-block; margin-left: 6px; }
.organiser-card-report .uks-report-btn,
.event-card-report-wrap .uks-report-btn {
    font-size: 10px;
    padding: 3px 10px;
}
/* BP private message — block-level wrap aligned right under the message bubble */
.uks-message-report-wrap {
    text-align: right;
    margin-top: 6px;
}
/* Public profile footer — single Report button centred under the grid.
   S100 26/05/26: align-items: center added so Report and Block (which differ
   in height) share the same text-baseline vertical centre per the universal
   vertical-alignment rule (BRAND_GUIDE §8.X). */
.profile-public-report-footer {
    display: flex;
    justify-content: center;
    align-items: center;
    margin: 24px 0 16px;
}
/* Event detail "Concern:" row */
.single-event-report-row { margin-top: 6px; }
/* Venue detail footer */
.venue-report-footer {
    display: flex;
    justify-content: center;
    margin: 16px 0 8px;
}
/* end of 34.2 */

/* 34.3 The shared modal — S92 rewrite: white card, navy text, brand tokens,
   compact, centred. `safe center` + outer `overflow-y: auto` keeps the card
   centred when it fits and falls back to scrollable-top when it doesn't. */
.uks-report-modal {
    position: fixed;
    inset: 0;
    z-index: 999999;
    display: flex;
    align-items: safe center;
    justify-content: center;
    padding: 4vh 16px;
    overflow-y: auto;
}
.uks-report-modal[hidden] { display: none; }
.uks-report-modal-overlay {
    position: absolute;
    inset: 0;
    background: rgba(3, 27, 131, 0.55);
    backdrop-filter: blur(2px);
}
.uks-report-modal-card {
    position: relative;
    background: #FFFFFF;
    border: 2px solid #CC9900;
    border-radius: 16px;
    box-shadow: 0 16px 56px rgba(3, 27, 131, 0.28), 0 4px 12px rgba(3, 27, 131, 0.12);
    padding: 22px 26px 18px;
    max-width: 440px;
    width: 100%;
    color: #031B83;
    font-family: 'Nunito Sans', sans-serif;
}
.uks-report-modal-close {
    border-radius: 10px; /* S234 21/09/26, D-508: the parent theme button default was leaking 9px. */
    position: absolute;
    top: 10px;
    right: 12px;
    background: none;
    border: none;
    font-size: 26px;
    color: #031B83;
    cursor: pointer;
    line-height: 1;
    padding: 4px 8px;
    transition: color 0.15s;
}
.uks-report-modal-close:hover { color: #CC9900; }
/* S217 (S217-V3, Rob 09/09/26): "the report card content is not centred." Every panel on the
   platform centres its content; this modal was the one left-aligned surface. Heading, blurb,
   both field labels, the reason rows and the two buttons are centred here. Nothing resizes. */
.uks-report-modal-title {
    font-family: Montserrat, sans-serif;
    font-size: 20px;
    font-weight: 700;
    color: #031B83;
    margin: 0 0 6px;
    line-height: 1.2;
    text-align: center;
}
.uks-report-modal-sub {
    font-size: 13px;
    color: #031B83;
    opacity: 0.78;
    margin: 0 0 14px;
    line-height: 1.45;
    text-align: center;
    /* S227 T-S224-036 (Rob, 15/09/26): "There should be a gold spacer under the top
       paragraph". The same 2px gold rule .uks-family-section-title and
       .uks-reviews-section-title already carry. 14px of air above it and 14px below
       (the margin already there), so the rule sits centred in its own gap. */
    padding-bottom: 14px;
    border-bottom: 2px solid #CC9900;
}
.uks-report-form fieldset.uks-report-reasons {
    border: none;
    padding: 0;
    margin: 0 0 12px;
}
.uks-report-reasons-legend {
    font-family: Montserrat, sans-serif;
    font-size: 16px;   /* S227 T-S224-036: Rob, "the label reason should be much bigger like an actual title". 16px is the platform --text-base step; the face is unchanged. */
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #031B83;
    padding: 0;
    margin-bottom: 8px;
    width: 100%;
    text-align: center;
}
/* S217 (S217-V9, Rob 09/09/26): "I have never liked the placement of the circle here, it is
   ridiculous, no multi-choice option has ever looked like that in the real world. Remove them
   circles, and just have the answers turn green on select like on the preferences questions."
   These rows now carry the .pf-opt geometry and the .pf-opt selected colours, value for value,
   so the two question surfaces are one look. The radio itself is hidden, not removed, so the
   form still posts and a keyboard or screen reader still sees a real radio group. */
/* S227 T-S224-033 (Rob: "massive empty space on the right hand side"). The rows measured
   28px from the left of a 440px card and 64px from the right. The 36px is
   theme-static.min.css\'s `input[type="checkbox"] + label, input[type="radio"] + label,
   .form-check-label, .form-check-wrapper { margin-right: 2rem; padding-left: calc(20px +
   0.5rem); font-size: 1rem; display: block; line-height: 1.6 }`. Seeko\'s JS adds
   .form-check-wrapper to every radio label at runtime, so that rule matched at the same
   (0,1,0) specificity as this one and won on source order, and .form-check-wrapper
   { display: block !important } beat the flex outright. One scope bump puts this rule at
   (0,2,0) and all five declarations apply again; nothing is stacked on top. */
/* S229 16/09/26 (T-S229-047, his 9 and 10): "because these are multiple choice questions with
   the switch on the right hand side, the text needs to be left aligned, not centered. So for
   once the text doesn't actually get centered in these response choices." */
.uks-report-modal .uks-report-reason {
    display: flex !important;
    align-items: center;
    justify-content: space-between;
    text-align: left;
    gap: 10px;
    padding: 15px 24px;
    border: 2px solid var(--color-gold, #CC9900);
    border-radius: 12px;
    cursor: pointer;
    margin: 0 0 8px;
    background: #FFFFFF;
    transition: border-color 0.15s, background 0.15s, box-shadow 0.15s;
    font-size: 15px;
    font-weight: 600;
    color: #031B83;
}
.uks-report-reason:hover {
    border-color: #CC9900;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.14);
}
.uks-report-reason input[type="radio"] {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}
.uks-report-reason > span {
    line-height: 1.2;
    flex: 1 1 auto;
    text-align: left;
}
.uks-report-reason input[type="radio"]:checked + span { font-weight: 600; color: #2F6B47; }
.uks-report-reason:has(input:checked) {
    border-color: #2F7D4F;
    background: #EAF4EC;
}
.uks-report-reason:has(input:checked) > span { color: #2F6B47; }
/* S217 (Rob raised this on 08/09/26 and it was still live). On an online event card the theme
   badge and the format badge sit on top of each other, so the theme is invisible on every online
   event. They are absolutely positioned from DIFFERENT parents - the theme badge from the image
   block at 14,14 and the online badge from the meta block at 12,12 - which is why neither rule
   knew about the other. The online badge drops below the theme badge, and only on a card that
   HAS a theme badge, so a card without one is untouched. */
.event-card:has(.event-card-image .event-card-badge) .event-card-badge-online {
    margin-top: 39px !important;
}

/* S217 (D-489, Rob's column rule: a partial last row is centred on the page centre line). The
   blog index is a Bootstrap row of post cards, and a Bootstrap row left-aligns whatever is left
   over: with four posts the fourth sat alone on the left of a 1100px row while the page centre
   was 550px away. Centring the row leaves a full row untouched and only moves the orphans. */
body.blog .content-wrapper .row,
body.archive .content-wrapper .row,
body.search .content-wrapper .row {
    justify-content: center;
}

/* S217 (Rob 09/09/26, looking at an organiser card): the interest control and the Report control
   sit one above the other on the same card and did not match - 78x30 with a 1px border and 12px
   text against 97x39 with a 2px border and 14px text. He asked for them to match. The interest
   control takes the Report control's geometry here and keeps its own colours, so a card carries
   one pair of controls rather than a big one and a small one. Scoped to the card footer: the same
   class is used at other sizes elsewhere and those are not what he was looking at. */
.event-card-footer .wishlist-button,
.event-card-footer .venue-save-btn {
    font-size: 14px !important;
    padding: 10px 24px 11px !important;
    border-width: 2px !important;
    border-radius: 10px !important;
}

/* S217 (GLOB-18 + D-499, Rob 09/09/26). The Best for chips on /suggest-location/ are meant to be
   plain pills: their real checkbox is display:none in the markup. Seeko draws its OWN box on the
   label's span and it landed on the first letter of every chip, so they read "ood for groups" and
   "olo-friendly". Same drawn-checkbox mechanism as the report reasons below. The pills also had a
   grey #ddd border and went navy when picked, so they take the gold border and the one selection
   green D-499 fixes for every answer list. The inline style on the label needs !important. */
#suggest-location-form label:has(input[name="location_styles[]"]) {
    border: 2px solid #CC9900 !important;
    padding: 6px 14px !important;
    /* S245 SUGGEST-1: the theme's .form-check-wrapper margin-right:2rem and label margin-bottom:.5rem (theme-static.min.css) put the chips 36px apart across
       and 9px down on top of the row's own 8px gap, so the gaps were uneven and a phone got one chip to a row; the row's 8px is the only space now. The
       grey label colour (seeko-dynamic.css .form-check-wrapper, rgba(51,51,51,.7)) takes the brand navy. */
    margin: 0;
    color: var(--color-navy);
}
/* The box is drawn by a span Seeko INJECTS into the label, `.check-icon`, whose ::before is the
   white square and ::after the tick. Hiding the input or the style-label's pseudos does nothing. */
#suggest-location-form label:has(input[name="location_styles[]"]) .check-icon {
    display: none !important;
}
#suggest-location-form label:has(input[name="location_styles[]"]:checked) {
    border-color: #2F7D4F !important;
    background: #EAF4EC !important;
}
#suggest-location-form label input[type="checkbox"]:checked + .style-label {
    color: #2F6B47 !important;
}

/* ==========================================================================================================================================
   S245 SUGGEST-1: the full visual sweep of /suggest-location/ (Rob, 05/10/26, on seeing it signed in: "there are no gold borders, left aligned
   text, grey boxes etc. It needs a full sweep.").

   NOTHING HERE IS NEW. Every value is the one the signed-off create-event card already shows on /submit-event/, READ OFF THE LIVE PAGE on the
   9th of October 2026 (computed values, not the source: the source of 69.4 says 12px 14px and 15px, the page paints 10px 12px and 14px because
   event-system.php's own inline CSS and 30.6.1 win there), and each is named where it comes from:
     the card            .ev-card            69.2
     the title           .ev-card__title     69.2
     the subtitle        .ev-card__hint      69.2, with .ev-card__head's 16px gap and 16px margin
     the field rows      .ev-field           69.3: a centred column, 8px gap, 24px between rows
     the labels          .ev-label           69.3 with 30.6.1 (Montserrat 700 navy) and the 5px under them
     the star            .ev-req             69.3: the dark gold, not the stray red #e44a4a
     the fields          .ev-input / .ev-textarea  69.4 with 69.20: 2px gold, radius 16, centred, navy, 460px at most
     the placeholders    69.4: navy at 65 per cent, italic, centred
     the hint line       .ev-note            69.x: 13px, secondary navy, 460px at most
     the file picker     .ev-file            69.11: the dashed gold row, the cream button with the dashed rule, the muted name
     the dropdown menu   .ev-dd__menu / .ev-dd__opt  (69.9): white, 2px gold, radius 12px, navy 13px 600, cream on hover
   WHY !important, and only where it is needed: the markup (event-system.php 20.3.1, the form's markup) carries its look as INLINE style attributes on the
   card, the title, the subtitle, the labels, the stars, the fields and the hint, and a stylesheet can only beat an inline attribute with !important
   (the dropdown width has the same problem with the page's own <style> block, which comes later in the document). The
   markup change that would let every !important below go is in the item's notes (the code lane). The chips' own rules are the S217 block
   just above (GLOB-18 and D-499), edited in place.
   ========================================================================================================================================== */

/* S245 SUGGEST-1.1 The card: a gold-bordered white panel. Before, no border at all, a 12px radius and a soft grey-black shadow, all inline. */
.venue-apply-card {
    border: 1.5px solid var(--color-gold);                 /* .ev-card (no inline border to beat) */
    border-radius: var(--radius-md) !important;            /* .ev-card, 16px (inline said 12px) */
    box-shadow: var(--shadow-sm) !important;               /* .ev-card (inline said 0 2px 16px rgba(0,0,0,.08)) */
    padding: var(--sp-2xl) !important;                     /* .ev-card, 32px (inline said 36px 32px) */
    text-align: center;                                    /* .ev-card */
}
/* On a phone the create-event card takes 24px above and below and 16px at the sides (.ev-card inside the 69.14 container query at 540px of the
   card's own container); the same here by viewport, so the content is as wide as it can be. */
@media (max-width: 600px) {
    .venue-apply-card { padding: var(--sp-xl) var(--sp-lg) !important; }
}
/* S245 SUGGEST-1.2 The title, as every card title on the create-event page: 36px Montserrat 700 navy, the 2px gold rule hugging the words, the
   same shadow. The theme's h2 (seeko-dynamic.css) had it at 2.37rem and weight 500 with no rule. margin: .ev-card__title's own 10px auto 21px plus
   the head's 16px flex gap, so the hint sits where it sits on the create-event cards. */
.venue-apply-card > h2 {
    font-family: var(--font-heading);
    font-size: 36px;
    font-weight: 700;
    color: var(--color-navy);
    margin: 10px auto 37px !important;                     /* inline said margin-bottom:4px */
    padding-bottom: 8px;
    border-bottom: 2px solid var(--color-gold);
    display: table;
    text-shadow: 0 4px 6px rgba(3,27,131,.18), 0 2px 4px rgba(3,27,131,.12);
}
/* S245 SUGGEST-1.3 The subtitle, as .ev-card__hint (13px, the secondary navy, 440px at most, centred); the 16px under it is the head's margin. */
.venue-apply-card > p {
    font-size: 13px;
    line-height: 1.5;
    color: var(--color-text-secondary);
    max-width: 440px;
    margin: 0 auto var(--sp-lg) !important;                /* inline said margin-bottom:24px */
    text-wrap: pretty;
}
/* S245 SUGGEST-1.4 The field rows: .ev-field, a centred column with an 8px gap and 24px between one row and the next. The last row keeps its own
   24px (inline) above the button. */
#suggest-location-form > div {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sp-sm);
}
#suggest-location-form > div:not(:last-of-type) { margin-bottom: 0 !important; }
#suggest-location-form > div + div { margin-top: var(--sp-xl); }
/* S245 SUGGEST-1.5 The labels, as .ev-label: Montserrat 700 13px, 0.04em, upper case, navy, centred, 5px under (inline said 600 and 4px). */
#suggest-location-form > div > label {
    font-family: var(--font-heading);
    font-weight: 700 !important;
    font-size: 13px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-navy);
    text-align: center;
    margin-bottom: 5px !important;
}
/* S245 SUGGEST-1.6 The required star, as .ev-req: the dark gold with 2px before it (inline said the stray red #e44a4a). */
#suggest-location-form > div > label > span {
    color: var(--color-gold-dark) !important;
    margin-left: 2px;
}
/* S245 SUGGEST-1.7 The fields, as .ev-input / .ev-textarea: 2px gold, radius 16, white, navy, centred, 460px at most, Nunito 14px with 10px 12px
   (read live). Before: a 1px grey #ddd border, radius 8, text on the left. */
#suggest-location-form input[type="text"],
#suggest-location-form textarea {
    width: 100%;
    max-width: 460px;
    box-sizing: border-box;
    padding: 10px 12px !important;
    font-family: var(--font-body);
    font-size: 14px !important;
    line-height: 1.6;
    color: var(--color-navy);
    background: var(--color-surface);
    border: 2px solid var(--color-gold) !important;
    border-radius: var(--radius-md) !important;
    text-align: center;
    margin-bottom: 0;                                      /* the theme's input and textarea margin-bottom:1rem (theme-static.min.css) stood down: the row gap above is the one space between rows */
}
#suggest-location-form textarea { line-height: 1.55; }
#suggest-location-form input[type="text"]::placeholder,
#suggest-location-form textarea::placeholder {
    color: rgba(3, 27, 131, 0.65) !important;
    font-style: italic;
    text-align: center;
    opacity: 1;
}
/* S245 SUGGEST-1.8 The dropdown is the create-event dropdown already (2px gold, radius 10, centred); it only needs the same 460px as the fields
   (event-system.php 20.3.1's inline <style> after the form says max-width:none). */
#suggest-location-form .ev-dd { max-width: 460px !important; }
/* S245 SUGGEST-1.9 The chips sit in a centred row (their own rule is the 7113 block above). */
#suggest-location-form div:has(> label > input[name="location_styles[]"]) {
    justify-content: center;
    width: 100%;
    margin-top: 0 !important;                              /* inline said 6px: the label's own 5px and the row's 8px gap are the space above every control */
}
/* S245 SUGGEST-1.10 The photo control, as the create-event file picker (.ev-file, 69.11): a dashed gold row, radius 16, the cream button with the
   dashed rule on its right and the file name in the muted navy. Before: the browser's own grey button. */
#suggest-location-form input[type="file"] {
    display: block;
    width: 100%;
    max-width: 460px;
    box-sizing: border-box;
    padding: 0;
    overflow: hidden;
    background: var(--color-surface);
    border: 2px dashed var(--color-gold);
    border-radius: var(--radius-md);
    font: 600 13px var(--font-body) !important;
    color: var(--color-text-muted);
    cursor: pointer;
}
#suggest-location-form input[type="file"]::file-selector-button {
    margin: 0 14px 0 0;
    padding: 12px 18px;
    font: 700 13px var(--font-heading);
    letter-spacing: 0.03em;
    color: var(--color-navy);
    background: var(--color-cream);
    border: 0;
    border-right: 2px dashed var(--color-gold);
    cursor: pointer;
    transition: background var(--duration-fast) var(--ease-out);
}
#suggest-location-form input[type="file"]:hover::file-selector-button { background: var(--color-cream-hover); }
/* S245 SUGGEST-1.11 The hint under the photo, as .ev-note (13px, the secondary navy, 460px at most, centred). Inline said 12px, on the left. */
#suggest-location-form > div > p {
    font-size: 13px !important;
    line-height: 1.55;
    max-width: 460px;
    margin: 2px auto 0 !important;
    text-align: center;
}
/* S245 SUGGEST-1.12 The button keeps the canonical .btn-option--lg (nothing changed on it); it takes the fields' 460px so its edges meet theirs,
   and centres in the form (inline said width:100%). */
#suggest-location-form { text-align: center; }
#suggest-location-submit { max-width: 460px; }
/* S245 SUGGEST-1.13 The message under the title after a press. Left on the left and in two off-brand colours (#3eb86a, #e44a4a, event-system.php
   the inline <style> after the form in 20.3.1): centred, in the token green and the token red (page-polish's own --color-success and --color-error). */
#suggest-location-feedback { text-align: center; }
#suggest-location-feedback p { margin: 0; }
#suggest-location-feedback p.success { color: var(--color-success); }
#suggest-location-feedback p.error { color: var(--color-error); }
/* S245 SUGGEST-1.14 The signed-out notice (and the "Suggestion Under Review" state, which shares its class): a bare left-hand line with no panel.
   It becomes the same gold-bordered card, with the body copy of the members-gate card (.uks-mgate__copy: Nunito 15px on 1.6, navy). The class
   .organiser-apply-gate has no other style anywhere and is used only by this shortcode. */
.organiser-apply-gate {
    max-width: 640px;
    margin: 0 auto;
    box-sizing: border-box;
    background: var(--color-surface);
    border: 1.5px solid var(--color-gold);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    padding: var(--sp-2xl) !important;
    text-align: center;
    font: 400 15px/1.6 var(--font-body);
    color: var(--color-navy);
}
.organiser-apply-gate p { margin: 0; }
.organiser-apply-gate p + p { margin-top: var(--sp-sm); }
/* The "Suggestion Under Review" state's title is the same card title as above (.ev-card__title), not the theme's plain h3. */
.organiser-apply-gate h3 {
    font-family: var(--font-heading);
    font-size: 36px;
    font-weight: 700;
    color: var(--color-navy);
    margin: 10px auto 21px;
    padding-bottom: 8px;
    border-bottom: 2px solid var(--color-gold);
    display: table;
    text-shadow: 0 4px 6px rgba(3,27,131,.18), 0 2px 4px rgba(3,27,131,.12);
}
/* S245 SUGGEST-1.15 The address suggestions Google draws under the Address field (.pac-container, grey borders, Arial, a grey pin): the site's
   dropdown menu look, .ev-dd__menu and .ev-dd__opt (white, 2px gold, radius 12, the 8px 24px shadow, navy 13px 600, cream on hover). Named through
   this page's body class because the container is appended to <body> and the same suggestions on /submit-event/ are not part of this item. The "powered by
   Google" logo Google draws under the list (.pac-container::after) is NOT touched: Google's terms require it. */
body.page-id-6968 .pac-container {
    margin-top: 10px;
    background: var(--color-surface);
    border: 2px solid var(--color-gold);
    border-radius: 12px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
    font-family: var(--font-body);
    overflow: hidden;
}
body.page-id-6968 .pac-item {
    padding: 10px 14px;
    border-top: 1px solid rgba(3, 27, 131, 0.2);
    font: 600 13px var(--font-body);
    color: var(--color-text-secondary);
    text-align: center;
    line-height: 1.4;
    cursor: pointer;
}
body.page-id-6968 .pac-item:first-child { border-top: 0; }
body.page-id-6968 .pac-item:hover,
body.page-id-6968 .pac-item-selected { background: var(--color-cream); }
body.page-id-6968 .pac-item-query { font-size: 13px; font-weight: 700; color: var(--color-navy); }
body.page-id-6968 .pac-icon { display: none; }
/* end of S245 SUGGEST-1 */

/* S217: the visible circle was never the input - Seeko hides the real radio and paints its own
   out of span::before (the ring) and span::after (the dot). Hiding the input alone left the
   drawn one on screen, which is why the first attempt still showed a circle. */
.uks-report-reason > span::before,
.uks-report-reason > span::after { content: none !important; display: none !important; }
/* S227: with the flex row restored (see .uks-report-modal .uks-report-reason above) the
   <span class="check-icon"> Seeko injects into every radio label becomes a flex item and
   the 10px gap pushes the label 5px right of centre. It draws nothing (its pseudos are
   killed on the line above), so it is hidden here exactly as #uks-panic-modal and
   #suggest-location-form already hide theirs. */
.uks-report-reason > span.check-icon { display: none !important; }
.uks-report-reason > span {
    padding-left: 0 !important;
    margin-left: 0 !important;
    line-height: 1.2;
    /* S227 T-S224-033. With the row restored to the card\'s full content width the
       longest reason ("Off-platform contact harvesting") fits on one line at 360 and,
       being centred, ran 13.23px UNDER the D-521 ring. The ring is absolute at
       right: 16px and is 22px wide, so it reaches 38px in from the padding edge while
       the row\'s own padding-right is 24px: it intrudes 14px into the content box on
       each side of a centred label, and the row\'s declared gap is 10px. 2 x (14 + 10)
       = 48px, so a centred label wraps before it can reach the ring and keeps the
       row\'s own 10px gap from it. Nothing moves at 768 and above, where the longest
       label is already narrower than this cap. */
    max-width: calc(100% - 48px);
}
.uks-report-notes-label {
    display: block;
    margin-bottom: 14px;
}
.uks-report-notes-label > span {
    display: block;
    font-family: Montserrat, sans-serif;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #031B83;
    margin-bottom: 6px;
    text-align: center;
}
.uks-report-notes-label textarea {
    width: 100%;
    padding: 10px 12px;
    border: 1.5px solid rgba(204, 153, 0, 0.35);
    border-radius: 10px;
    font-family: 'Nunito Sans', sans-serif;
    font-size: 13.5px;
    color: #031B83;
    background: #FFFFFF;
    resize: vertical;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.uks-report-notes-label textarea::placeholder {
    color: rgba(3, 27, 131, 0.65);
    opacity: 0.5;
    font-style: italic;
    /* S224 15/09/26. Rob on the report pop-up: "center the placeholder text". Only the
       PLACEHOLDER is centred, not the field: a note someone types is prose and belongs on the
       left, and centring the value would make a three-line answer unreadable. */
    text-align: center;
}
html[data-nav="kbd"] .uks-report-notes-label textarea:focus {
    border-color: #CC9900;
    outline: none;
    box-shadow: 0 0 0 3px rgba(204, 153, 0, 0.18);
}
.uks-report-modal-actions {
    display: flex;
    justify-content: center;
    gap: 10px;
    margin-top: 4px;
}
/* Modal action buttons — visual rules retired S100 (25/05/26).
   .uks-report-submit-btn now uses class="uks-report-submit-btn btn-dashboard"
   — styling owned by .btn-dashboard in §43.
   .uks-report-cancel-btn is currently un-touched in HTML (still has just its
   own class) — visual styling not yet swapped. Flagged for Rob's decision
   on whether Cancel inside a submit modal is Option or Dashboard. */
/* S222 item 109 (Rob, 14/09/2026): "Submitting, like when something is saving or submitting,
   it should not be just completely grayed out like that. So use the same styling as the saving
   button." This halved the whole button on top of 43.2's disabled rule, painting 1.50 to 1.
   The in-flight look is 43.2's now, so this rule only has to stop the second fade. */
.uks-report-submit-btn:disabled {
    opacity: 1;
    cursor: not-allowed;
}
/* S222 item 109, second half (Rob): "And the same with the cancel button as well. Like it looks
   smaller. It does not look like that is now the standard cancel button." Measured in the live
   modal: Cancel 66.8 x 30.4 with a 1px border and 12px text against Submit 143.8 x 39 with a 2px
   border and 14px text. This is the same pair problem Rob ruled on in S217 on the event card
   footer, and it takes the same answer: the smaller control takes the larger one's geometry and
   keeps its own colours, scoped to this container so .btn-option is untouched everywhere else.
   line-height is included because .btn-option sets 1.2 and .btn-dashboard sets 1; without it the
   button measured 41.8 tall against 39. Measured after: both 39.00 tall, midpoints 0.00 apart. */
.uks-report-modal-actions .uks-report-cancel-btn {
    font-size: 14px !important;
    line-height: 1 !important;
    letter-spacing: normal !important;
    padding: 10px 24px 11px !important;
    border-width: 2px !important;
    border-radius: 10px !important;
}
.uks-report-form-error {
    margin-top: 12px;
    padding: 10px 14px;
    background: #FFFBE6;
    border: 1.5px solid #CC9900;
    border-radius: 10px;
    color: #031B83;
    font-size: 13px;
    font-weight: 600;
}
/* end of 34.3 */

/* 34.4 Confirmation toast */
.uks-report-toast {
    /* S227 item 124: same fault and same fix as 36.4 - see there. uksocials-reports.php:241
       supplies the top once this reads absolute. Measured before: rect.top held at 706.41
       across a 400px scroll. Measured after, on a real submission: top 706px written inline.
       THE COLOURS ARE LEFT ALONE ON PURPOSE. Rob named the Blocked toast when he said "the
       red colours, not blue" and said nothing about this one, so it stays navy on gold until
       he rules. */
    position: absolute;
    left: 50%;
    transform: translateX(-50%) translateY(20px);
    /* S229 16/09/26 (T-S229-047, his 8): "The shape is now correct, but the colour isn't. Why
       is it blue? If it's a pop-up like that, make it the light cream styling." */
    background: var(--color-cream, #FFFBE6);
    color: var(--color-navy, #031B83);
    /* S234 21/09/2026, Rob, from his phone: "the label is a little too high ... they should all be
       centred together properly in that panel." MEASURED on the live toast at 1280: the panel ran
       y 120.0 to 168.8 (mid 144.40) while the painted ink of the line ran 138.7 to 148.0 (mid
       143.35), so the label stood 1.05px high. The cause is the line box, not the padding: this
       string carries no descender, so its ink is cap-top to baseline, and Chromium centres the
       LINE box (Montserrat ascent 11.8, descent 2.8 at 13px), which is not the same centre. The
       padding is split by that measured amount, 13 over 11 rather than 12 over 12, which puts the
       ink on the panel centre line and leaves the panel height untouched. */
    padding: 13px 24px 11px;
    border-radius: 10px;  /* D-508, as 36.4 */
    border: 2px solid #CC9900;
    font-family: Montserrat, sans-serif;
    font-size: 13px;
    font-weight: 700;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
    z-index: 1000000;
    opacity: 0;
    transition: opacity 0.25s, transform 0.25s;
    max-width: 90vw;
    text-align: center;
}
/* 34.4a .uks-report-toast-dash - the separator, sitting on the label centre line. Same ruling
   and the same sentence: "the dash is not centred properly either". MEASURED on the live toast
   rendered at eight times size: with no lift the hyphen ink centre sat 10.5px below the label
   ink centre at that scale, so 1.3125px below it at the real one, which is the amount taken off
   here. IT IS A TRANSFORM AND NOT A RELATIVE OFFSET, and that is the whole of why an earlier
   attempt missed: Chromium rounds top on a relatively positioned inline box to a whole pixel, so
   -1.35px painted as -1px and -1.7px as -2px, landing 0.35px low and 0.65px high in turn. A
   transform keeps the fraction, and inline-block is what lets an inline element take one. It
   moves nothing in the line box, so the panel keeps its size. The character stays a hyphen: Rob
   asked for the dash to be centred, not for it to be replaced. */
.uks-report-toast-dash {
    display: inline-block;
    transform: translateY(-1.3125px);
}
.uks-report-toast[hidden] { display: none; }
.uks-report-toast.is-visible {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}
/* end of 34.4 */

/* end of 34 */


/* ============================================================================
   35. SECTION: No-screens agreement pill (S84 — A30 / D131)
   Phone-with-strikethrough icon + "No screens" label. Distinct visual from
   the age-group pill — uses navy-on-cream with a subtle gold border + a small
   crossed-phone glyph so attendees notice the agreement before they RSVP.
   Renders on event cards (alongside age pill, top-right), event detail info
   panel, and invite cards.
   ============================================================================ */

/* 35.1 Pill on event card image — sits below the age pill when both present */
.event-card-image .event-no-screens-pill {
    position: absolute;
    top: 42px;
    right: 10px;
    background: #031B83;
    color: #FFFBE6;
    border: 2px solid #CC9900;
    border-radius: 9999px;
    padding: 4px 10px 4px 8px;
    font-family: Montserrat, sans-serif;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.18);
    z-index: 2;
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
/* When no age pill is present, snug to the top */
.event-card-image:not(:has(.event-age-pill)) .event-no-screens-pill {
    top: 10px;
}
.event-no-screens-pill-icon {
    font-size: 13px;
    filter: grayscale(0.4);
    opacity: 0.95;
}
/* end of 35.1 */

/* 35.2 Inline pill (event detail info row, invite card) */
.single-event-info-row .event-no-screens-pill,
.invite-card-no-screens-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: #031B83;
    color: #FFFBE6;
    border: 2px solid #CC9900;
    border-radius: 9999px;
    padding: 4px 12px;
    font-family: Montserrat, sans-serif;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.invite-card-no-screens-pill {
    margin: 6px 0;
    align-self: flex-start;
}
/* end of 35.2 */

/* 35.3 Event detail "Agreement:" row layout */
.single-event-no-screens-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}
.single-event-no-screens-detail {
    display: block;
    width: 100%;
    margin-top: 4px;
    font-size: 13px;
    color: #555;
    line-height: 1.5;
    font-family: 'Nunito Sans', sans-serif;
}
/* end of 35.3 */

/* 35.4 Event create form — branded tickbox treatment for the No Screens toggle */
.event-no-screens-toggle {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 16px;
    background: #FFFBE6;
    border: 2px solid #CC9900;
    border-radius: 12px;
    cursor: pointer;
    font-weight: 600 !important;
    color: #031B83 !important;
    transition: background 0.15s, border-color 0.15s;
    margin-bottom: 0;
}
.event-no-screens-toggle:hover { background: #FFF6CC; }
.event-no-screens-toggle input[type="checkbox"] {
    margin: 4px 0 0 0;
    accent-color: #CC9900;
    width: 18px;
    height: 18px;
    flex-shrink: 0;
}
.event-no-screens-toggle-label {
    line-height: 1.4;
}
/* end of 35.4 */

/* 35.5 Invite-create modal — match the existing business_only toggle style */
.invite-no-screens-toggle { /* inherits .invite-business-toggle styles already applied above by sharing the class */ }
/* end of 35.5 */

/* end of 35 */


/* ============================================================================
   36. SECTION: Block-a-member button + confirm modal + Blocked-members settings
   list (S84 — A6 / D132)
   The Block button sits next to Report on every profile + each received BP
   message. Visual treatment: muted-red pill so it's clearly destructive but
   doesn't shout. Confirm modal mirrors the Report modal's branded shell with
   a destructive "Block" submit button. Unblock variant uses the standard
   white-with-gold-border treatment.
   ============================================================================ */

/* 36.1 Block button — destructive but understated.
   S100 26/05/26: margin: 0 !important added to override Seeko's
   `button { margin-bottom: 1rem }` which was making Block's margin-box 18px
   taller than its content, causing the flex parent's align-items: center to
   centre on the margin-box (visible content then sat 9px above Report). */
/* S198 29/08/26, Rob: "those buttons should be the same, just the red one uses the red
   instead". Block sat beside Report as a different control entirely - 25px tall against
   39px, a 9999px pill against a 10px radius, 11px UPPERCASE with letter-spacing against
   14px sentence case, and a grey shadow against the navy one. It now takes the same
   geometry Report uses (.btn-dashboard) and changes only the colour: red border, red
   label, on the same cream fill. The red-fill hover inversion below is unchanged. */
/* S229 16/09/26 (T-S229-047, his 6): "The block button should not have a cream background, it
   should be white. In fact, no, the reds have a light red background. So it shouldn't be white
   or cream, it should be light red." Same wash the Reported button and the platform's error
   pills use. */
.uks-block-btn {
    background: var(--color-error-bg, rgba(196, 28, 28, 0.06));
    /* S227 items 121/122: #c0392b is a Flat-UI red and is not on the palette. The Reported
       button beside this one is the brand error red, and Rob asked for report and block to
       be standardised on every profile type. Same cream face, same geometry, brand red. */
    color: var(--color-error, #C41C1C);
    border: 2px solid var(--color-error, #C41C1C);
    border-radius: 10px;
    padding: 10.5px 24px;
    font-family: Montserrat, sans-serif;
    font-size: 14px;
    font-weight: 700;
    text-transform: none;
    letter-spacing: normal;
    cursor: pointer;
    line-height: 14px;
    margin: 0 !important;
    transition: background 0.2s, color 0.2s, border-color 0.2s, box-shadow 120ms ease-out, transform 120ms ease-out;
    /* S245 row 130 (Rob: "the drop shadows are so completely different between these buttons ... make sure they all have them"): the ONE shadow at rest. This was the BRAND_GUIDE 9.1
       navy pair of May 2026 (0 2px 0 + 0 3px 6px rgba(3,27,131,.10)), MEASURED live on a member's profile footer beside Report, whose rest shadow is `0 4px 12px rgba(0,0,0,.16)` (the
       signed-off dashboard buttons' too, D-640 and D-655): Rob's S198 ruling is that these two "should be the same, just the red one uses the red instead". */
    box-shadow: var(--shadow-gold-hover);
}
/* S227 item 122, Rob: "Nothing should be just solid colour like that - no blue, no gold, no
   red." The red-fill inversion is replaced with the darker cream every other cream button on
   the platform uses on hover (BRAND_GUIDE 9.3), keeping the red label and border. This also
   restates border-color, which seeko-dynamic.css clears on any button hover. */
.uks-block-btn:hover:not(:disabled) {
    background: rgba(196, 28, 28, 0.12);
    color: var(--color-error, #C41C1C);
    border-color: var(--color-error, #C41C1C);
}
/* S244 row 112 (Rob, the 8th of October 2026: "all the buttons that do something negative like delete or report, they don't have the full animation, they don't pop when you
   hover"). Block is the red half of the pair "the same, just the red one uses the red instead" (S198), and the Report button beside it pops on hover (lift translateY(-1px) and
   the 0 4px 4px + 0 8px 18px navy shadow, .btn-dashboard:hover, 43.2) while Block only deepened its wash: measured live on a member's profile with a real pointer, hovered, Block
   transform none and the shadow unchanged; held down, Seeko's grey #eee with a #191919 label and no ring. Block now takes Report's lift and shadow on hover (a real pointer
   only and not while held, with the transition list above extended to carry them) and, pressed, the darker red wash with its own ring and label and no shadow. The
   Unblock variant (the same element with .uks-block-btn-unblock added, the cream and navy button below) is excluded from both and is exactly as it was.
   S245 row 130: the shadow named above (the navy two-layer lift of 43.2) is replaced by the ONE shadow, --shadow-gold-hover, the same as Block's rest shadow now and as Report's. */
@media (hover: hover) {
.uks-block-btn:not(.uks-block-btn-unblock):hover:not(:disabled):not(:active) {
    box-shadow: var(--shadow-gold-hover);
    transform: translateY(-1px);
}
}
.uks-block-btn:not(.uks-block-btn-unblock):not([disabled]):not(.disabled):active {
    background: rgba(196, 28, 28, 0.12);
    color: var(--color-error, #C41C1C);
    border-color: var(--color-error, #C41C1C);
    box-shadow: none;
}
html[data-nav="kbd"] .uks-block-btn:focus-visible {
    outline: 2px solid #031B83;
    outline-offset: 2px;
}
/* Unblock variant — non-destructive, use the standard brand button */
.uks-block-btn-unblock {
    background: #FFFBE6;
    color: #031B83;
    border-color: #CC9900;
}
.uks-block-btn-unblock:hover:not(:disabled) {
    background: #031B83;
    color: #CC9900;
    border-color: #CC9900;
}
/* end of 36.1 */

/* 36.2 Surface placement */
.uks-message-block-wrap {
    text-align: right;
    margin-top: 4px;
}
/* Profile footer — already wrapped in .profile-public-report-footer; both
   buttons sit side-by-side via flex */
.profile-public-report-footer {
    flex-wrap: wrap;
    gap: 10px;
}
/* end of 36.2 */

/* 36.3 Confirm modal */
.uks-block-modal {
    position: fixed;
    inset: 0;
    z-index: 999999;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
}
.uks-block-modal[hidden] { display: none; }
.uks-block-modal-overlay {
    position: absolute;
    inset: 0;
    background: rgba(3, 27, 131, 0.55);
    backdrop-filter: blur(2px);
}
.uks-block-modal-card {
    position: relative;
    /* S227 item 122, Rob: "it should have a white background". Its sibling, the Report
       modal card, already measures rgb(255,255,255). */
    background: #FFFFFF;
    border: 2px solid #CC9900;
    border-radius: 16px;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
    padding: 28px 28px 24px;
    max-width: 460px;
    width: 100%;
    color: #031B83;
    font-family: 'Nunito Sans', sans-serif;
}
.uks-block-modal-close {
    border-radius: 10px; /* S234 21/09/26, D-508: the parent theme button default was leaking 9px. */
    position: absolute;
    top: 8px;
    right: 12px;
    background: none;
    border: none;
    font-size: 28px;
    color: #031B83;
    cursor: pointer;
    line-height: 1;
    padding: 4px 8px;
}
.uks-block-modal-close:hover { color: #CC9900; }
.uks-block-modal-title {
    font-family: Montserrat, sans-serif;
    font-size: 20px;
    font-weight: 700;
    color: #031B83;
    margin: 0 0 12px;
    text-align: center;
}
.uks-block-modal-body {
    text-align: center;
    margin: 0 0 20px;
    font-size: 14px;
    line-height: 1.55;
    color: #031B83;
}
/* S229 16/09/26 (T-S229-047, his 7): "Nothing in that block is centered... the title isn't
   centered the body of text isn't centered the buttons aren't centered." */
.uks-block-modal-actions {
    display: flex;
    justify-content: center;
    gap: 10px;
}
.uks-block-cancel-btn,
.uks-block-confirm-btn {
    /* S227 item 122, Rob: "the wrong style". Measured against the Report modal on the same
       page (.uks-report-cancel-btn.btn-option / .uks-report-submit-btn.btn-dashboard), which
       is the standard these two should already have been on: 10px corners (D-508), 14px,
       sentence case, no letter-spacing, 10px 24px 11px, the platform two-part navy shadow.
       These were 8px, 13px, UPPERCASE with 0.5px tracking and no shadow. */
    /* S231 18/09/26: back to symmetric. Sub-pixel padding cannot move painted text here - 6.1875
     and 6.375 rendered identically - so the nudge is a transform on the label span below, the
     same mechanism item 17 needed. */
  padding: 6px 24px;
    font-family: Montserrat, sans-serif;
    font-size: 14px;
    font-weight: 700;
    text-transform: none;
    letter-spacing: normal;
    border-radius: 10px;
    /* box-shadow: the rest shadow now stands in the rule directly below (S245 row 130, block modal), where it can beat Seeko's button:focus. */
    cursor: pointer;
    border: 2px solid;
    transition: background 0.15s, color 0.15s, border-color 0.15s, box-shadow 120ms ease-out, transform 120ms ease-out;
}
/* S245 row 130, the Block dialog (Rob, the 9th of October 2026, on the Block panel: Block's shadow must match Cancel's, at rest, hovered and held). The ONE rest shadow,
   --shadow-gold-hover (0 4px 12px rgba(0,0,0,0.16), as the dashboard buttons Rob signed off and Cancel already carry it), moved here from the shared rule above, where it stood at 0,1,0 and
   the Block button painted NONE. MEASURED LIVE (DevTools protocol, example_aaron_fitzgerald, a member's profile, Block opened): uksocials-blocks.php:290 runs confirmBtn.focus() the moment the
   dialog opens (Block and Unblock), and Seeko's parent theme carries `button:focus { box-shadow: rgba(0,0,0,.5) 0 0 0 0 }` at 0,1,1, which out-ranked the 0,1,0 rule: the focused Block read
   rgba(0,0,0,0.5) 0 0 0 0 (stable for 2.4 seconds, so not a transition) while the unfocused Cancel read 0 4px 12px rgba(0,0,0,0.16), and the pixels under Block were pure white. C2's harness said
   Block was canonical because it pressed Cancel, which moved the focus there, before it read Block's rest (L-135). THE FIX stays where the shadow is defined, as the calendar's going ring does
   at 46.CAL1 (S190): the :focus states are listed on the rule, which count 0,2,0 and beat the parent with no !important. Cancel takes the same line, so tabbing to it cannot take its shadow
   away either. The :focus selectors are NOT added to the shared rule above because its `border: 2px solid` shorthand would then beat .uks-block-cancel-btn's border-color (0,1,0) and reset the
   ring colour of a focused button. Hover (0,4,0 and 0,5,0, below) already carries the same shadow and wins over this rule; held (box-shadow: none at 0,4,0 and 0,5,0, below) wins over it;
   the in-flight disabled rules at the end of 36.3 (0,3,0) still take it off. */
.uks-block-cancel-btn,
.uks-block-cancel-btn:focus,
.uks-block-confirm-btn,
.uks-block-confirm-btn:focus {
    box-shadow: var(--shadow-gold-hover);
}
.uks-block-cancel-btn {
    /* the standard cancel is transparent over the panel, not a white block on a white panel */
    background: transparent;
    color: #031B83;
    border-color: #CC9900;
}
/* S244 rows 112 and 119 (Rob, the 8th of October 2026: the negative buttons "don't pop when you hover", and the canonical states): the Block panel's two buttons had the fill
   on hover and nothing else. MEASURED LIVE with a real pointer on a member's Block panel: Cancel hovered painted the cream with the ring GONE (Seeko's border-color transparent)
   and the label #191919, no lift; Block hovered the deeper wash with nothing else moving; both held down painted Seeko's grey #eee with a #191919 label and no ring. They are
   brought onto the Report panel they were written to mirror (the comment above): Cancel takes .uks-report-cancel-btn.btn-option's hover (cream, the ring, the black
   two-layer shadow and the lift, 43.1), Block takes .uks-report-submit-btn.btn-dashboard's (the navy two-layer shadow and the lift, 43.2) with its own red wash and ring; pressed is
   the darker cream (the 12 percent wash on Block), the ring and label kept, no shadow. A real pointer only and not while held, as the other buttons here. The Unblock
   confirm (.is-unblock) is excluded from the new rules and is exactly as it was.
   S245 row 130: Cancel's black two-layer shadow and Block's navy one (two different shadows on the two buttons of one panel) are replaced by the ONE shadow, --shadow-gold-hover,
   which both buttons already carry at rest (the shared rule above) and so keep when hovered. */
.uks-block-cancel-btn:hover { background: #FFFBE6; border-color: #CC9900; color: #031B83; }
@media (hover: hover) {
.uks-block-cancel-btn:hover:not(:disabled):not(:active) {
    box-shadow: var(--shadow-gold-hover);
    transform: translateY(-1px);
}
.uks-block-confirm-btn:not(.is-unblock):hover:not(:disabled):not(:active) {
    box-shadow: var(--shadow-gold-hover);
    transform: translateY(-1px);
}
}
.uks-block-cancel-btn:not([disabled]):not(.disabled):active {
    background: #FFF5CC;
    border-color: #CC9900;
    color: #031B83;
    box-shadow: none;
}
.uks-block-confirm-btn:not(.is-unblock):not([disabled]):not(.disabled):active {
    background: rgba(196, 28, 28, 0.12);
    border-color: var(--color-error, #C41C1C);
    color: var(--color-error, #C41C1C);
    box-shadow: none;
}
.uks-block-confirm-btn {
    /* S227 item 122, Rob: "the block button shouldn't be solid red like that - Nothing should
       be just solid colour like that". The platform's ruled shape for a destructive control is
       the error token as a light wash with a darker border and darker text: the same pair the
       Reported state (34.1) and the Decline button use. Measured before: rgb(192,57,43) with
       white text. The shadow is inherited from the shared rule above. */
    background: var(--color-error-bg, rgba(196, 28, 28, 0.06));
    color: var(--color-error, #C41C1C);
    border-color: var(--color-error, #C41C1C);
}
.uks-block-confirm-btn:hover:not(:disabled) {
    /* a deeper wash of the same token; the label and border do not move. */
    background: rgba(196, 28, 28, 0.12);
    color: var(--color-error, #C41C1C);
    border-color: var(--color-error, #C41C1C);
}
.uks-block-confirm-btn.is-unblock {
    /* S207 05/09/26, Rob item A4: gold FILL out, light cream in with a gold border and navy text; darker cream on hover and select. */
    background: var(--color-cream, #FFFBE6);
    color: #031B83;
    border-color: #CC9900;
}
.uks-block-confirm-btn.is-unblock:hover:not(:disabled) {
    /* S207 05/09/26, Rob item A4: hover is the DARKER cream, not a navy invert. */
    background: var(--color-cream-hover, #FFF5CC);
    color: var(--color-navy, #031B83);
    border-color: var(--color-gold);
}
/* S222: three hardcoded greys (#ccc on #ccc with #666 text), all three on BRAND_GUIDE 1.6.1's
   banned list, the same fault that was taken off the Reported state at 34.1 on 14/09/2026.
   COMPUTED before: rgb(102,102,102) on rgb(204,204,204), 3.58 to 1. The button is disabled only
   while the block request is in flight (uksocials-blocks.php:291 also swaps the label), so 46.Z
   applies: it keeps its own colours and the label change is the feedback.
   The colours are RESTATED here rather than left to the base rule. Measured live on the real
   block panel with the colours deleted, the button painted white on rgb(248,248,248) at 1.06 to 1,
   because the base .uks-block-confirm-btn rule carries no !important and Seeko's own broad button
   rule wins. Restating them measured rgb(255,255,255) on rgb(192,57,43), 4.95 to 1. */
/* S227: this forced the destructive fill onto EVERY disabled state, so the Unblock variant
   (cream, navy, gold) turned into a red button while the request was in flight. D-528: a busy
   button looks like the active one and the word is the feedback, and uksocials-blocks.php:291
   already supplies that word. So each variant keeps its own colours. */
.uks-block-confirm-btn:disabled:not(.is-unblock) {
    background: var(--color-error-bg, rgba(196, 28, 28, 0.06)) !important;
    color: var(--color-error, #C41C1C) !important;
    border-color: var(--color-error, #C41C1C) !important;
    opacity: 1;
    cursor: not-allowed;
    box-shadow: none;
}
.uks-block-confirm-btn.is-unblock:disabled {
    background: var(--color-cream, #FFFBE6) !important;
    color: #031B83 !important;
    border-color: #CC9900 !important;
    opacity: 1;
    cursor: not-allowed;
    box-shadow: none;
}
.uks-block-modal-error {
    margin-top: 12px;
    padding: 10px 14px;
    /* S227: #f8d7da with #721c24 is Bootstrap alert-danger and neither colour is on the
       palette. Same light-wash shape as the Reported state, 10px to match this panel. */
    background: var(--color-error-bg, rgba(196, 28, 28, 0.06));
    border: 1.5px solid var(--color-error, #C41C1C);
    border-radius: 10px;
    color: var(--color-error, #C41C1C);
    font-size: 13px;
}
/* end of 36.3 */

/* 36.4 Toast (mirrors Reports toast) */
.uks-block-toast {
    /* S227 item 121, Rob: "the toast ... stuck to the display so that when you scrolled it
       moved down". Measured before: rect.top held at 685.61 while scrollY went 5107 -> 5507.
       absolute with NO top and NO bottom here: uksocials-blocks.php:265 supplies the one value
       only the runtime knows, the document coordinate of the spot it is standing on, and it
       does so only once this reads absolute. One owner per property. Measured after: top
       5793px written by that code, and rect.top moved -400.00 for a +400 scroll. */
    position: absolute;
    left: 50%;
    transform: translateX(-50%) translateY(20px);
    /* Rob: "blocked should be the red colours, not blue." --color-error on --color-error-bg,
       the pair the Reported pill uses. The wash is composited onto white rather than left
       transparent because this floats over the navy footer (121.jpeg), where 6 percent would
       show the navy through and drop the text to about 1.5 to 1. Composited: #C41C1C on
       #FCF1F1, about 5.7 to 1. */
    background: #FCF1F1;
    color: var(--color-error, #C41C1C);
    padding: 12px 24px;
    /* Rob: "no idea why this notification has massive rounded sides". D-508: 10px. */
    border-radius: 10px;
    border: 2px solid var(--color-error, #C41C1C);
    font-family: Montserrat, sans-serif;
    font-size: 13px;
    font-weight: 700;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
    z-index: 1000000;
    opacity: 0;
    transition: opacity 0.25s, transform 0.25s;
    max-width: 90vw;
    text-align: center;
}
.uks-block-toast[hidden] { display: none; }
/* F-044 (S234, 21/09/2026). Rob: the "Unblocked." toast rendered in exactly the same red as
   "Blocked." Blocking is the destructive half of the pair and keeps the error red above; UNBLOCKING
   restores a member and is the positive half, so it takes the platform's one positive pair, the
   #EAF4EC / #2F7D4F / #2F6B47 that D-499 made the single source of truth for a confirmed positive
   state (a picked option, a shown interest, a checked chip, a selected panic reason). Measured
   composited: #2F6B47 on #EAF4EC is 5.69 to 1, the same as the red pair's 5.7 to 1, so the wash
   still reads where the toast floats over the navy footer. The state class is set by
   uksocials-blocks.php 1.3, which already knows which of the two actions ran. */
.uks-block-toast.is-unblock {
    background: #EAF4EC;
    border-color: #2F7D4F;
    color: #2F6B47;
}
.uks-block-toast.is-visible {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}
/* end of 36.4 */

/* 36.5 Blocked Members settings page list */
.uks-blocks-settings {
    max-width: 720px;
    margin: 0 auto;
    padding: 12px 0 32px;
    font-family: 'Nunito Sans', sans-serif;
    color: #031B83;
}
.uks-blocks-heading {
    font-family: Montserrat, sans-serif;
    font-size: 22px;
    font-weight: 700;
    color: #031B83;
    margin: 0 0 8px;
    text-align: center;
}
.uks-blocks-intro {
    margin: 0 0 24px;
    text-align: center;
    color: #555;
    line-height: 1.5;
    font-size: 14px;
}
.uks-blocks-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.uks-blocks-list-row {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 18px;
    background: #FFFFFF;
    border: 2px solid #CC9900;
    border-radius: 12px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
}
.uks-blocks-list-sigil img,
.uks-blocks-list-sigil .avatar {
    width: 56px;
    height: 56px;
    border-radius: 9999px;
    object-fit: cover;
    border: 2px solid #CC9900;
    background: #FFFBE6;
    display: block;
}
.uks-blocks-list-body {
    flex: 1;
    min-width: 0;
}
.uks-blocks-list-name {
    font-family: Montserrat, sans-serif;
    font-weight: 700;
    color: #031B83;
    font-size: 15px;
    line-height: 1.2;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.uks-blocks-list-meta {
    font-size: 12px;
    color: #888;
    margin-top: 2px;
}
.uks-blocks-list-empty {
    text-align: center;
    color: #888;
    padding: 32px 16px;
    background: #FFFBE6;
    border: 2px dashed #CC9900;
    border-radius: 12px;
}
@media (max-width: 540px) {
    .uks-blocks-list-row { flex-wrap: wrap; }
    .uks-blocks-list-unblock-btn { margin-left: auto; }
}
/* end of 36.5 */

/* end of 36 */


/* ============================================================================
   37. SECTION: Under-18 Panic Button — persistent shield + high-contrast modal
   (S84 — A7 / D133)
   Departs from the navy + gold + cream brand palette in favour of HIGH-
   CONTRAST red + white. This is intentional + brand-aligned: the shield
   is a child-safety surface, and Ofcom Children's Code §15 + standard
   child-safety UX both require unmistakable visual treatment. Brand-
   first standing rule still respected — the deliberate departure is
   documented in D133.
   ============================================================================ */

/* 37.1 "Get help" as the LAST row of the dashboard left menu
   D-634 (Rob's ruling, 21/09/2026): "the GET HELP button must be the LAST item in the dashboard
   left menu, under Suggestions, styled like the other menu items but red". What used to be here
   was the floating pill: position fixed, bottom 24px, right 24px, its own uppercase type and its
   own drop shadow. He described it as "randomly stuck to the right hand side of the page". Those
   rules are REPLACED, not overridden and not hidden, so nothing can put the pill back.

   The row now takes ALL of its geometry from .sidenav__item (41.4) because it carries that class:
   47px tall, 10px radius, the 1px border, the 11px padding and the same 27px glyph column. That is
   what makes it line up with Suggestions above it. Only the colour is different, and the colour is
   the whole point: D133 rules the child-safety surface a deliberate departure from navy + gold +
   cream to high-contrast red and white, so this is the one red row in a navy-on-cream menu and it
   cannot be mistaken for anything else. The white shield inside it is the same mark, drawn as an
   inline SVG (uksocials-panic.php 1.1a) instead of the CSS background image it used to be.

   D-446 (dashboard only) is satisfied by where the markup lives rather than by a rule here: the
   sidenav is rendered only on the member's own dashboard surfaces.

   The selectors are scoped under .sidenav and carry !important because 41.4's own rest and hover
   states are themselves !important, and because the row is a <button>, which arrives with the
   theme's button metrics (a bottom margin among them) that must not survive. */
.sidenav .sidenav__item--panic {
    /* Measured off the live menu rather than copied from 41.4: every other row carries the legacy
       .sidenav-item class as well, and profile-editor.css gives THAT class a 12px gap which wins on
       cascade order, so the real gap between glyph and label is 12px and not the 8px 41.4 declares.
       This row does not carry the legacy class (it must stay out of the AJAX nav's way), so it takes
       the same token directly and its label starts on the same x as Suggestions above it.
       justify-content is restated because a <button> centres its content and a menu row does not. */
    gap: var(--space-md, 12px);
    justify-content: flex-start;
    margin: 0 !important;
    -webkit-appearance: none;
    appearance: none;
    background: #C41C1C !important;
    border: 1px solid #C41C1C !important;
    border-radius: 10px !important;
    color: #FFFFFF !important;
    box-shadow: none !important;
    text-transform: none;
    letter-spacing: 0;
    text-decoration: none;
}
.sidenav .sidenav__item--panic:hover,
.sidenav .sidenav__item--panic:focus {
    background: #A52D22 !important;
    border-color: #A52D22 !important;
    color: #FFFFFF !important;
}
html[data-nav="kbd"] .sidenav .sidenav__item--panic:focus-visible {
    outline: 2px solid #031B83;
    outline-offset: 2px;
}
/* The label inherits the row's white rather than the menu's navy, and never wraps: at the narrow
   widths where the sidenav turns into a horizontal scroller the rows size to their own content. */
.sidenav .sidenav__item--panic .sidenav__item-label {
    color: inherit;
    white-space: nowrap;
}
/* end of 37.1 */

/* 37.2 High-contrast modal */
/* S224 14/09/26, item 217: the card measured 7.50px left of the viewport centre and it was
   centred perfectly INSIDE this box, so the box was the fault: it measured 1265 in a 1280
   viewport. An ancestor on the dashboard carries will-change/transform, which makes it the
   containing block for a fixed child, so inset:0 resolved against that ancestor rather than the
   viewport. 100vw is measured from the viewport itself and does not care about the containing
   block, and the page behind is locked while the modal is open so there is no scrollbar for vw
   to overshoot. */
.uks-panic-modal {
    position: fixed;
    inset: 0;
    width: 100vw;
    z-index: 999999;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
}
.uks-panic-modal[hidden] { display: none; }
/* S224 14/09/26, item 217. The card measured 7.50px left of the viewport centre, which is exactly
   half the page's 15px scrollbar: the panel centres on the content box while the scrollbar eats
   the difference. Locking the page behind removes the scrollbar, so the card centres truly, and
   it also stops the page scrolling underneath an open modal, which it was doing. */
html:has(.uks-panic-modal:not([hidden])),
body:has(.uks-panic-modal:not([hidden])) {
    /* both axes, and !important, because the theme sets overflow-x: clip on body and the
       shorthand alone was resolving to "clip visible" and leaving the scrollbar in place. */
    overflow-x: hidden !important;
    overflow-y: hidden !important;
}
.uks-panic-modal-overlay {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.60);
    backdrop-filter: blur(2px);
}
.uks-panic-modal-card {
    position: relative;
    background: #FFFFFF;
    border-radius: 16px;
    box-shadow: 0 12px 48px rgba(0, 0, 0, 0.40);
    max-width: 520px;
    width: 100%;
    max-height: 92vh;
    overflow-y: auto;
    color: #031B83;
    font-family: 'Nunito Sans', sans-serif;
}

/* 37.2.1 Red header band — instantly recognisable as safety-critical */
.uks-panic-modal-header {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 18px 22px;
    /* S222 (T-S219-034), Rob: "remove all the reds because it will scare them". The band takes the
       site's navy; the mark and the title stay white on it. */
    /* S229 16/09/26 (T-S229-047, his 15): "it shouldn't be solid blue, and the shield and the
       get help title should be bigger and green." The band takes the card's own white with the
       platform's gold rule under it, and the mark and title take the platform green. */
    background: #FFFFFF;
    color: #2F6B47;
    border-bottom: 2px solid #CC9900;
    border-radius: 16px 16px 0 0;
}
.uks-panic-modal-icon {
    display: inline-block;
    width: 34px;
    height: 34px;
    font-size: 0;
    line-height: 0;
    flex-shrink: 0;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232F6B47' stroke-width='2' stroke-linejoin='round' stroke-linecap='round'%3E%3Cpath d='M12 2.5 20 5.5v6c0 5-3.4 8.9-8 10.5-4.6-1.6-8-5.5-8-10.5v-6z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 34px 34px;
}
.uks-panic-modal-title {
    font-family: Montserrat, sans-serif;
    font-size: 28px;
    font-weight: 700;
    color: #2F6B47;
    margin: 0;
    flex: 1;
}
.uks-panic-modal-close {
    background: none;
    border: none;
    border-radius: 10px; /* S234 21/09/26, D-508: the parent theme button default was leaking 9px. */
    color: #031B83;
    font-size: 28px;
    line-height: 1;
    cursor: pointer;
    padding: 4px 8px;
    margin-left: 8px;
}
.uks-panic-modal-close:hover { color: #CC9900; }
/* end of 37.2.1 */

/* 37.2.2 Body */
.uks-panic-modal-body {
    padding: 20px 24px 16px;
}
/* S224 14/09/26, item 217. Rob, shown the whole panel live: "look at all the text each little
   block of text is left aligned it should all be centered", and on the headings "they should all
   actually be more prominent they're too small as it is and they should all be the same and
   centered". The answer ROWS are not centred: D-521 is his own standard and puts the label left
   with the ring at the right end. */
.uks-panic-modal-intro {
    margin: 0 0 18px;
    font-size: 14.5px;
    line-height: 1.55;
    color: #031B83;
    text-align: center;
}
.uks-panic-form fieldset.uks-panic-reasons {
    border: none;
    padding: 0;
    margin: 0 0 16px;
}
/* S224: the three field headings now share ONE treatment, bigger and centred. */
.uks-panic-reasons-legend,
.uks-panic-who-label > span,
.uks-panic-notes-label > span {
    display: block;
    width: 100%;
    font-family: Montserrat, sans-serif;
    font-size: 16px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #031B83;
    padding: 0;
    margin: 0 0 10px;
    text-align: center;
}
.uks-panic-who-hint {
    display: block;
    text-align: center;
    margin-top: 6px;
}
/* S222 14/09/26 (T-S219-034), ROB: "this list should be like the other lists that have now been
   made standard like from preferences when there's multiple choice meaning the little circle should
   be on the right hand side and then when they've chosen one it goes green remove all the reds
   because it will scare them if a youngster is genuinely nervous and anxious and then they're going
   to report someone and you have everything in bright red it could put them off so keep all the
   standard styling". So this list takes the .pf-opt values (page-polish 12307 onwards): the row
   geometry, the 22px ring at the RIGHT end, and the green chosen state. The native radio is not
   hidden, it IS the ring (appearance:none), so it keeps its keyboard behaviour and its label.
   SCOPED TO #uks-panic-modal on purpose: theme-static.min.css carries
   `input[type="radio"] + label {display:block; padding-left:29px}` at 0-1-2 and loads AFTER this
   file, so a bare class lost display:flex and gained a 29px left pad (measured live, both). */
#uks-panic-modal .uks-panic-reason {
    /* !important on display alone: theme-static.min.css carries a `display:block !important` that
       matches this label, so specificity cannot win it. Measured on the live modal, not assumed. */
    display: flex !important;
    align-items: center;
    gap: 12px;
    padding: 15px 20px;
    /* S195 Rob: "keep the red bits red but replace all the grey and black shit with actual
       brand colours" - resting rows were #ddd on #FAFAFA with inherited grey text. Gold
       border, cream fill, navy text; the red hover/selected states are untouched. */
    border: 2px solid var(--color-gold, #CC9900);
    border-radius: 12px;
    cursor: pointer;
    margin-bottom: 8px;
    /* S227 15/09/26, item 217, Rob: "it's not centered". theme-static.min.css gives every
       .form-check-wrapper a margin-right of 2rem, and this row carries that class, so each
       answer row stopped 32px short of the card's right edge at 360 and 36px at 1280 while its
       left edge stayed on the panel's own 24px. Measured 24/56 before and 24/24 after, at all
       five of his widths. */
    margin-right: 0;
    background: var(--color-surface, #FFFFFF);
    color: #031B83;
    transition: border-color 0.15s, background 0.15s;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.4;
}
/* The parent theme's JS injects its own <span class="check-icon"></span> into every label as the
   fake radio. It is empty, so with flex:1 it was eating half the row and pushing the wording into
   the middle (measured: two 173px spans in a 436px row). It goes; the real input is the ring. */
#uks-panic-modal .uks-panic-reason > span.check-icon {
    display: none !important;
}
#uks-panic-modal .uks-panic-reason > span:not(.check-icon) {
    flex: 1;
    min-width: 0;
    overflow-wrap: anywhere;
    /* The parent theme replaces a radio with its own circle drawn as span::before at left:0, and
       pads the label 29px to clear it (measured: a 20px circle, border #666, position absolute).
       That grey circle is the thing Rob is looking at. It goes, the real input becomes the ring. */
    padding-left: 0 !important;
    text-align: left;
}
#uks-panic-modal .uks-panic-reason > span::before,
#uks-panic-modal .uks-panic-reason > span::after {
    content: none !important;
    display: none !important;
}
#uks-panic-modal .uks-panic-reason input[type="radio"] {
    opacity: 1 !important;    /* the theme hides the real control; here it IS the control */
}
/* S195: the parent theme paints label text rgba(51,51,51,.7) with a selector that outranks a
   bare class, so the navy is pinned with the modal's own ancestry (the sanctioned cascade
   scope-bump for parent-theme conflicts; measured, not guessed). */
#uks-panic-modal .uks-panic-reason,
#uks-panic-modal .uks-panic-reason > span { color: #031B83; }
#uks-panic-modal .uks-panic-reason:hover { border-color: var(--color-gold, #CC9900); background: var(--color-surface-raised, #FFFBE6); }
#uks-panic-modal .uks-panic-reason input[type="radio"] {
    order: 2;                     /* the text is flex:1 and comes first, so the ring sits right */
    appearance: none;
    -webkit-appearance: none;
    position: relative;
    margin: 0;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    border: 2px solid var(--color-gold, #CC9900);
    background: transparent;
    flex-shrink: 0;
    cursor: pointer;
    transition: border-color 0.15s;
}
#uks-panic-modal .uks-panic-reason input[type="radio"]::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 10px;
    height: 10px;
    margin: -5px 0 0 -5px;
    border-radius: 50%;
    background: #2F7D4F;
    transform: scale(0);
    transition: transform 0.15s;
}
/* S224 14/09/26, item 217. Rob: "For some reason the first option, the circle, has a black
   outline." The panel puts the cursor on the first radio when it opens, and what he saw was the
   BROWSER's own focus outline, rgb(16,16,16) auto 1px, on an auto-focused control. D-514 says a
   ring paints only for keyboard navigation, so it is gated the same way as the other 46 rules. */
#uks-panic-modal .uks-panic-reason input[type="radio"]:focus { outline: none; }
html[data-nav="kbd"] #uks-panic-modal .uks-panic-reason input[type="radio"]:focus-visible {
    outline: 2px solid var(--color-gold, #CC9900);
    outline-offset: 2px;
}
#uks-panic-modal .uks-panic-reason input[type="radio"]:checked { border-color: #2F7D4F; }
#uks-panic-modal .uks-panic-reason input[type="radio"]:checked::after { transform: scale(1); }
/* S195: same ancestry as the navy pin above, so the checked RED still wins over it. */
#uks-panic-modal .uks-panic-reason input[type="radio"]:checked ~ span:not(.check-icon) { font-weight: 700; color: #2F6B47; }
#uks-panic-modal .uks-panic-reason:has(input:checked) {
    border-color: #2F7D4F;
    background: #EAF4EC;
}

.uks-panic-notes-label {
    display: block;
    margin-bottom: 14px;
}
/* S224: the 12px version of this label is gone; it shares the one heading rule above. */
.uks-panic-notes-label textarea {
    width: 100%;
    padding: 10px 12px;
    border: 2px solid #CC9900; /* S195 Rob: brand gold, was grey #ddd */
    border-radius: 8px;
    font-family: 'Nunito Sans', sans-serif;
    font-size: 14px;
    color: #031B83;
    background: #FFFFFF;
    resize: vertical;
}
html[data-nav="kbd"] .uks-panic-notes-label textarea:focus {
    border-color: var(--color-gold, #CC9900);
    outline: none;
    box-shadow: 0 0 0 2px rgba(204, 153, 0, 0.25);
}

/* S224 14/09/26, item 217. Rob: "There's another option at the bottom saying I want to speak to
   somebody and that's not the same as the options above, it's not a proper tick box option." It
   was a cream strip with a 20px browser checkbox on the LEFT, against five white answer rows with
   the control on the right. It now takes the answer row's own geometry from D-521: white ground,
   2px gold, 12px corners, 15px/20px padding, the control at the RIGHT end. */
/* The element carries the parent theme's own form-check-wrapper and label-checkbox classes, and
   theme-static.min.css sets display:block on those at a specificity that !important alone did not
   beat: measured, the rule applied every property EXCEPT display, so the row stayed a block and
   the box stayed top-left. Scoping to the modal id wins it outright. Same family as D-527's
   finding on the event form. */
#uks-panic-modal label.uks-panic-talk-label,
.uks-panic-talk-label {
    display: flex !important;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 15px 20px;
    background: #FFFFFF;
    border: 2px solid #CC9900;
    border-radius: 12px;
    margin-bottom: 16px;
    /* S227 15/09/26, item 217. The same 2rem that theme-static.min.css puts on every
       .form-check-wrapper. Rob's ruling is that this row matches the answer rows, so it takes
       the same correction: measured 24/56 before and 24/24 after. */
    margin-right: 0;
    cursor: pointer;
    font-size: 14px;
    font-weight: 700;
    color: #031B83;
    /* the parent theme stamps padding-left: calc(20px + .5rem) on any label it treats as a
       checkbox wrapper, which is the same trap D-527 records for the event form. */
    padding-left: 20px !important;
    padding-right: 20px !important;
}
/* The theme also takes this input OUT OF FLOW (position:absolute; left:20px) and draws its own
   box on an injected span.check-icon, which is why order:2 alone moved nothing. Measured: with
   the input put back in flow and the injected span hidden, the control lands 22px from the row's
   right edge, which is its 20px padding plus the 2px border. The reason rows above already do
   exactly this; the talk row was the one that had been left out. D-527 records the same trap. */
#uks-panic-modal label.uks-panic-talk-label > span.check-icon { display: none !important; }
#uks-panic-modal label.uks-panic-talk-label input[type="checkbox"],
.uks-panic-talk-label input[type="checkbox"] {
    position: static !important;
    order: 2;
    flex: 0 0 auto;
    margin: 0;
    /* the browser's own checkbox is all but invisible on white at this size, so it takes the
       answer rows' 22px gold ring instead and fills green when ticked, which is what Rob means
       by "a proper tick box option" like the ones above it. */
    /* the theme also sets the real input to opacity 0 so it can draw its own box on the injected
       span; with that span hidden the control was invisible. The reason radios above already
       carry the same opacity: 1 !important for exactly this reason. */
    opacity: 1 !important;
    appearance: none;
    -webkit-appearance: none;
    width: 22px;
    height: 22px;
    border: 2px solid var(--color-gold, #CC9900);
    border-radius: 6px;
    background: #FFFFFF;
    cursor: pointer;
    position: relative;
}
#uks-panic-modal label.uks-panic-talk-label input[type="checkbox"]:checked {
    border-color: #2F7D4F;
    background: #2F7D4F;
}
#uks-panic-modal label.uks-panic-talk-label input[type="checkbox"]:checked::after {
    content: "";
    position: absolute;
    left: 5px;
    top: 1px;
    width: 6px;
    height: 11px;
    border: solid #FFFFFF;
    border-width: 0 2.5px 2.5px 0;
    transform: rotate(45deg);
}
/* the whole row turns green when ticked, exactly as the answer rows above do; scoped to the id
   because the resting white above is scoped there too and would otherwise win. */
#uks-panic-modal label.uks-panic-talk-label:has(input:checked),
.uks-panic-talk-label:has(input:checked) {
    border-color: #2F7D4F;
    background: #EAF4EC !important;
    color: #2F6B47;
}

.uks-panic-form-error {
    margin-bottom: 12px;
    padding: 10px 14px;
    background: #ffd6d6;
    border-left: 4px solid #C41C1C;
    border-radius: 8px;
    color: #721c24;
    font-size: 13.5px;
    line-height: 1.4;
}

/* S224: the pair was right-aligned in a panel whose every other block is centred. */
.uks-panic-modal-actions {
    display: flex;
    justify-content: center;
    gap: 10px;
    margin-top: 4px;
}
.uks-panic-cancel-btn,
.uks-panic-submit-btn {
    padding: 12px 24px;
    font-family: Montserrat, sans-serif;
    font-size: 14px;
    font-weight: 700;
    /* S224: the rest of the panel is sentence case; these two were shouting. 10px corners is
       D-508's radius, which every other button on the platform already takes. */
    text-transform: none;
    letter-spacing: 0.3px;
    border-radius: 10px;
    cursor: pointer;
    border: 2px solid;
    transition: background 0.15s, border-color 0.15s;
}
.uks-panic-cancel-btn {
    /* S195 Rob: brand navy on white with gold border, was grey #888 on #ccc */
    background: #FFFFFF;
    color: #031B83;
    border-color: #CC9900;
}
.uks-panic-cancel-btn:hover {
    background: #FFFBE6;
    border-color: #CC9900;
    color: #031B83;
}
.uks-panic-submit-btn {
    /* S222 (T-S219-034), Rob: the standard styling. These are .btn--primary's own live values:
       cream ground, navy label, 2px gold. */
    background: #FFFBE6;
    color: #031B83;
    border-color: var(--color-gold, #CC9900);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
}
.uks-panic-submit-btn:hover:not(:disabled) {
    background: #FFFFFF;
    border-color: var(--color-gold, #CC9900);
}
/* S222: S195 had already taken this one off grey, but it still fades the whole button to .55
   while the panic alert is Sending... COMPUTED before: rgb(116,130,187) on rgb(255,253,241),
   3.65 to 1. Of every in-flight button on the platform this is the one a member reads under the
   most stress, so it follows 46.Z with the rest: full navy on cream, label change as feedback. */
.uks-panic-submit-btn:disabled {
    background: #FFFBE6;
    color: #031B83;
    border-color: #CC9900;
    opacity: 1;
    cursor: not-allowed;
    box-shadow: none;
}
/* end of 37.2.2 */

/* 37.2.3 External cross-links — NSPCC / Childline / 999 */
/* S224 14/09/26, item 217. Rob: "the very bottom section should be the red colours because that
   is an emergency and the content should be centered as well." This does NOT contradict D-521,
   which took red off the ANSWER LIST so a frightened child is not met with a wall of it. This is
   the 999 and Childline block, where red is the point. It takes the platform's own error tokens
   in the shape Rob approved for Decline: a light wash, a darker border, darker text, never a
   solid block of red. */
.uks-panic-external {
    background: var(--color-error-bg, rgba(196, 28, 28, 0.06));
    border-top: 2px solid var(--color-error, #C41C1C);
    padding: 18px 24px 22px;
    border-radius: 0 0 16px 16px;
    color: var(--color-error, #C41C1C);
    text-align: center;
}
.uks-panic-external-heading {
    margin: 0 0 10px;
    font-family: Montserrat, sans-serif;
    font-size: 16px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    text-align: center;
    color: var(--color-error, #C41C1C);
}
.uks-panic-external-list {
    margin: 0;
    padding: 0;
    list-style: none;
}
.uks-panic-external-list li {
    padding: 6px 0;
    font-size: 14px;
    line-height: 1.5;
    text-align: center;
    color: var(--color-error, #C41C1C);
    border-bottom: 1px dashed rgba(196, 28, 28, 0.35);
}
.uks-panic-external-list li:last-child { border-bottom: 0; }
.uks-panic-external-list strong {
    font-family: Montserrat, sans-serif;
    color: var(--color-error, #C41C1C);
    font-size: 16px;
}
.uks-panic-external-list a {
    color: var(--color-error, #C41C1C);
    text-decoration: underline;
    font-weight: 700;
}
.uks-panic-external-list a:hover { color: #031B83; }
/* end of 37.2.3 */

/* end of 37.2 */

/* 37.3 Confirmation toast (slightly longer dwell than other toasts — child
   safety warrants the user actually reading it) */
.uks-panic-toast {
    position: fixed;
    bottom: 24px;
    left: 50%;
    transform: translateX(-50%) translateY(20px);
    background: #031B83;
    color: #CC9900;
    padding: 14px 28px;
    border-radius: 9999px;
    border: 2px solid #CC9900;
    font-family: Montserrat, sans-serif;
    font-size: 13.5px;
    font-weight: 700;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
    z-index: 1000000;
    opacity: 0;
    transition: opacity 0.25s, transform 0.25s;
    max-width: 92vw;
    text-align: center;
}
.uks-panic-toast[hidden] { display: none; }
.uks-panic-toast.is-visible {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}
/* end of 37.3 */

/* end of 37 */


/* ============================================================================
   38. SECTION: Family Link settings page — pending + active list
   (S84 — A8 / D134)
   The Family sub-tab inside /settings/. Mirrors the Blocked Members tab
   visual rhythm (white card rows, gold border, sigil + name + meta + action)
   plus the explicit attestation tickbox on incoming pending requests.
   ============================================================================ */

/* 38.1 Page wrapper */
.uks-family-settings {
    max-width: 760px;
    margin: 0 auto;
    padding: 12px 0 32px;
    font-family: 'Nunito Sans', sans-serif;
    color: #031B83;
}
.uks-family-heading {
    font-family: Montserrat, sans-serif;
    font-size: 22px;
    font-weight: 700;
    color: #031B83;
    margin: 0 0 8px;
    text-align: center;
}
.uks-family-intro {
    margin: 0 0 28px;
    text-align: center;
    /* S206 04/09/2026 - Rob: "everything needs to be centered and it needs to be on brand". #555 was
       an off-brand grey; the platform has no grey body text outside the marketing pages. */
    color: var(--color-navy);
    line-height: 1.55;
    font-size: 14px;
}
.uks-family-section-title {
    font-family: Montserrat, sans-serif;
    font-size: 14px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #031B83;
    margin: 24px 0 12px;
    padding-bottom: 6px;
    border-bottom: 2px solid #CC9900;
}
.uks-family-empty {
    text-align: center;
    color: var(--color-navy);   /* S206: was #888 */
    padding: 24px 16px;
    background: #FFFBE6;
    border: 2px dashed #CC9900;
    border-radius: 12px;
    margin: 0;
}
/* end of 38.1 */

/* 38.1b THE REQUEST FORM, CENTRED AND ON BRAND (S206 04/09/2026).
   Rob, on the live page: "loads of those fields and their content are not centered and the username
   bit with the ampersand is not blue, it's grey". The inputs were inheriting a left-aligned,
   grey-texted default from the settings form they sit inside. */
.uks-family-request-form,
.uks-family-request-row {
    text-align: center;
}
.uks-family-request-form .uks-family-handle-wrap,
.uks-family-request-row .uks-family-handle-wrap {
    justify-content: center;
    margin-left: auto;
    margin-right: auto;
}
.uks-family-handle-input,
.uks-family-relationship-input {
    text-align: center;
    color: var(--color-navy);
    margin-left: auto;
    margin-right: auto;
    display: block;
}
.uks-family-handle-input::placeholder {
    color: rgba(3, 27, 131, 0.65);
    text-align: center;
}
.uks-family-at,
.uks-family-handle-prefix {
    color: var(--color-navy);
    font-weight: 700;
}
.uks-family-request-btn {
    display: block;
    margin: 12px auto 0;
}
/* end of 38.1b */

/* 38.1c THE CONNECTION-CODE CARDS (S206 04/09/2026).
   Rob on the live page: "Lots of gray still... 'Get a new code' and 'Got someone's code' and the
   input field are all way too close to each other - space them out more, and uniformly in relation
   to the rest of the page... the centering includes input field content, not just body text or
   titles." These blocks had no rules at all, so every one of them fell back to the browser default:
   near-black text, left-aligned input content, and no vertical rhythm. */
.st-connect-card {
    max-width: 520px;
    margin: 0 auto 28px;
    padding: 24px 20px;
    text-align: center;
    /* S206: white, not cream - Rob: "the background of those panels is the same color as the
       button. So make them white." */
    background: #fff;
    border: 2px solid var(--color-gold);
    border-radius: 16px;
    color: var(--color-navy);
}
.st-connect-card * { color: var(--color-navy); }

/* S207 05/09/26 (visual item 7): the shared-card Authorise another account? panel on the holder dashboard, on the same card
   as the connection-code cards above. Rendered once, below the dashboard heading (uksocials-shared-bank-authorisation.php 9.2).
   Scoped under .workspace so it outranks the generic .workspace .card rule (8800) that gave it a 1px border and black text. */
.workspace .card.uks-sba-panel, .uks-sba-panel {
    max-width: 640px;
    margin: 0 auto 28px;
    padding: 24px 20px;
    text-align: center;
    background: #fff;
    border: 2px solid var(--color-gold);
    border-radius: 16px;
    color: var(--color-navy);
}
.workspace .uks-sba-panel *, .uks-sba-panel * { color: var(--color-navy); }
.uks-sba-panel__title { font-size: 20px; font-weight: 700; margin: 0 0 10px; }
.uks-sba-panel__intro, .uks-sba-req__who, .uks-sba-req__state { font-size: 14px; line-height: 1.55; margin: 0 0 12px; text-align: center; }
.uks-sba-req { padding-top: 12px; border-top: 1px solid rgba(204, 153, 0, 0.35); margin-top: 12px; }
.uks-sba-req__actions { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }
.uks-sba-req__actions .btn-option { margin: 0; }
.st-connect-card__label {
    font-family: Montserrat, sans-serif;
    font-weight: 700;
    font-size: 15px;
    margin-bottom: var(--sp-xl);
}
/* S235 25/09/2026 (item 26, Rob: needs some spacers and things). Reuses the existing
   card-title gold spacer pattern already live on the wishlist event cards (.wl-card__rule:
   60% width, gold, 1.5px, radius 1px) so this card title carries the same divider
   underneath it, per Rob's standard for a card title. */
.st-connect-card__rule {
    width: 60%;
    height: 1.5px;
    margin: 0 auto var(--sp-xl);
    background: var(--color-gold);
    border-radius: 1px;
}
/* D-641 24/09/2026: one line saying what the code is, so it reads as a family or friends
   connection code rather than a referral code. */
.st-connect-card__sublabel {
    font-size: 13px;
    line-height: 1.55;
    margin: 0 auto var(--sp-xl);
    max-width: 400px;
    color: var(--color-text-muted);
}
.st-connect-card__code {
    font-family: Montserrat, sans-serif;
    font-size: 24px;
    font-weight: 700;
    letter-spacing: 3px;
    /* R3-26b 25/09/2026 (Rob: "put the code on a white button like the 'got someone's code'
       one"). Values copied from #uks-connect-code-in's own computed styles (measured live,
       width 360): background rgb(255, 255, 255), border 2px solid rgb(204, 153, 0),
       border-radius 12px, padding 12px 14px, box-sizing border-box, width 100% capped at
       max-width 300px and centred. box-sizing: border-box plus the fixed line-height below
       reserve the same height whether or not a code is present, so this also replaces the old
       S206 min-height/line-height jump guard (a bare min-height cannot hold a bordered,
       padded box to one height; border-box sizing does). */
    box-sizing: border-box;
    line-height: 30px;
    background: #fff;
    border: 2px solid var(--color-gold);
    border-radius: 12px;
    width: 100%;
    max-width: 300px;
    margin: 0 auto var(--sp-xl);
    /* R3-26b ink-centring (dpr 8 and dpr 2.625 at 412, 50 percent coverage, 4 different
       generated codes): base 12px pushed the ink 0.438px above true centre, so padding-top
       carries a +0.876px correction (vertical is a 1:1 ratio: raising padding-top by X moves
       the box's own midline by X/2 and the text by X, netting X/2 back towards it). Held to
       within 0.125px to 0.247px on every code and both densities tested. */
    padding-top: 12.876px;
    padding-right: 14px;
    padding-bottom: 12px;
    /* GATE-RERUN 25/09/2026 (gate 12): the asymmetric +2.376px correction this section used to
       carry (an attempt to counter the trailing letter-spacing gap) was never measured by
       comparison.js's own ink gate, and the gate measured the code 1.18px right of true centre
       with it applied - a sub-pixel trick that did not hold. Reverted to symmetric padding,
       matching padding-right (Rob's stated preference over asymmetric corrections that only
       hold at one density). Verified by comparison.js current R3-26: dx within gate 12's
       0.5px tolerance. */
    padding-left: 14px;
    /* D-640 25/09/2026: the box is clickable (tap to copy), so it carries the gold shadow at
       rest like every other clickable on the platform. */
    box-shadow: var(--shadow-gold-hover);
    /* D-641 24/09/2026: gold and bold so it reads as the important, copyable value, matching
       the button standard's gold-on-cream language without needing a background of its own. */
    color: var(--color-gold);
}
.st-connect-card__code[role="button"] { cursor: pointer; }
.st-connect-card__code[role="button"]:hover,
.st-connect-card__code[role="button"]:focus-visible {
    text-decoration: underline;
    text-decoration-color: var(--color-gold);
}
/* D-640 25/09/2026: pressed while copying, darker cream and no shadow, matching every other
   clickable on the platform; resets the instant the tap ends. */
.st-connect-card__code[role="button"]:active {
    background: var(--color-cream-hover);
    box-shadow: none;
}
.st-connect-card__code.is-copied { color: #2d6a2e; }
.st-connect-card__expiry { font-size: 13px; margin-bottom: var(--sp-xl); }
.st-connect-card__note   { font-size: 13px; line-height: 1.55; margin: 0 auto var(--sp-xl); max-width: 400px; }
/* S206: the generic settings-form input rules were winning on specificity, leaving a grey 1px
   border and a #9a9a9a placeholder. Scoped to the card so these land. */
.st-connect-card input.st-connect-card__input {
    display: block;
    width: 100%;
    max-width: 300px;
    margin: 0 auto var(--sp-xl);
    padding: 12px 14px;
    text-align: center;            /* the CONTENT centres, not just the box */
    letter-spacing: 3px;
    text-transform: uppercase;
    color: var(--color-navy);
    background: #fff;
    border: 2px solid var(--color-gold);
    border-radius: 12px;
    font-family: Montserrat, sans-serif;
    font-size: 16px;
}
.st-connect-card input.st-connect-card__input::placeholder {
    color: rgba(3, 27, 131, 0.65);
    text-align: center;
    letter-spacing: 2px;
}
/* S206: the username placeholder read as grey rather than a light blue. Rob: "make it more
   obviously blue." */

/* S235 25/09/2026 (item 26): this copy-status line carried no rule of its own, so it fell
   back to the theme paragraph default (24px bottom margin) even while empty, adding a
   stray gap between the code and the Works once line the uniform rhythm did not account
   for. Same :empty collapse already proven on the result line directly below. */
.st-connect-card__code-status:empty { display: none; }
.st-connect-card__code-status { font-size: 13px; margin: 0 0 var(--sp-xl); }
/* S224 item 13: empty, this status line still held min-height 18px + 18px top margin =
   36.00px of dead space under Look them up. It collapses while empty and comes straight
   back when the lookup writes into it. */
.st-connect-card__result:empty { display: none; }
.st-connect-card__result { font-size: 13px; line-height: 1.55; margin: var(--sp-xl) auto 0; max-width: 420px; min-height: 18px; }
.st-connect-card .btn-option {
    margin: 0 auto;
    background: var(--color-cream) !important;
    box-shadow: var(--shadow-gold-hover) !important;
}
/* D-641 24/09/2026: the D-640 standard button, gold shadow at rest; darker cream and no
   shadow while pressed or in flight, matching the existing disabled rule that already
   drops the shadow. */
.st-connect-card .btn-option:hover {
    background: var(--color-cream) !important;
    box-shadow: var(--shadow-gold-hover) !important;
}
.st-connect-card .btn-option:active,
.st-connect-card .btn-option:disabled {
    background: var(--color-cream-hover) !important;
    box-shadow: none !important;
}
/* S217 (no grey or black text, Rob's standing rule). The cookie consent panel is the FIRST
   thing a new visitor sees. Its body copy had been brought onto navy at some point but its
   heading, its five category buttons and its Always Active label had not: rgb(33,33,33) and a
   pure rgb(0,128,0), neither of which is in the brand guide. The plugin ships them, so they are
   overridden here rather than in its own stylesheet, which an update would replace. */
.cky-preference-title,
.cky-accordion-btn,
.cky-preference-header,
.cky-accordion-header-des,
.cky-notice-des p,
.cky-preference-content-wrapper p {
    color: var(--color-navy, #031B83) !important;
}
.cky-always-active {
    color: #27A644 !important;
    font-weight: 600 !important;
}

/* S217 (GLOB-09, Rob: /stripe-connect/ "needs improvement"). The Stripe account id printed in
   Bootstrap's default code pink, rgb(232, 62, 140), a colour in no part of the brand guide, on
   the page an organiser sees the moment they connect their bank. Printed the way the platform
   prints every other inline value instead: navy on cream inside a gold hairline. */
.stripe-connect-wrapper code {
    color: var(--color-navy, #031B83) !important;
    background: var(--color-cream, #FFFBE6) !important;
    border: 1px solid var(--color-gold, #CC9900) !important;
    border-radius: 6px !important;
    padding: 2px 8px !important;
    font-size: 13px !important;
}
/* S219 (Rob 10/09/26 on item 127): the chip sat 2px below its label because the two boxes centre
   differently on a shared baseline. A centred row puts both on one centre line. */
.stripe-connect-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 6px;
}
/* end of 38.1c */



/* 38.2 List rows */
.uks-family-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.uks-family-list-row {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 14px 18px;
    background: #FFFFFF;
    border: 2px solid #CC9900;
    border-radius: 12px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
    flex-wrap: wrap;
}
.uks-family-list-sigil img,
.uks-family-list-sigil .avatar {
    width: 56px;
    height: 56px;
    border-radius: 9999px;
    object-fit: cover;
    border: 2px solid #CC9900;
    background: #FFFBE6;
    display: block;
}
.uks-family-list-body {
    flex: 1;
    min-width: 200px;
}
.uks-family-list-name {
    font-family: Montserrat, sans-serif;
    font-weight: 700;
    color: #031B83;
    font-size: 15px;
    line-height: 1.2;
}
.uks-family-list-meta {
    font-size: 13px;
    color: #555;
    margin-top: 4px;
    line-height: 1.45;
}
.uks-family-list-actions {
    display: flex;
    flex-direction: column;
    gap: 6px;
    align-items: stretch;
    min-width: 130px;
}
.uks-family-list-actions button {
    padding: 8px 16px;
    font-family: Montserrat, sans-serif;
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    border-radius: 9999px;
    cursor: pointer;
    border: 2px solid;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
    white-space: nowrap;
}
.uks-family-list-actions .uks-family-accept {
    /* S207 05/09/26, Rob item A4: gold FILL out, light cream in with a gold border and navy text; darker cream on hover and select. */
    background: var(--color-cream, #FFFBE6);
    color: #031B83;
    border-color: #CC9900;
    box-shadow: 0 2px 6px rgba(0,0,0,0.10);
}
.uks-family-list-actions .uks-family-accept:hover { background: var(--color-cream-hover, #FFF5CC); color: var(--color-navy, #031B83); border-color: var(--color-gold); }
    /* S207 05/09/26, Rob item A4: hover is the DARKER cream, not a navy invert. */
.uks-family-list-actions .uks-family-decline,
.uks-family-list-actions .uks-family-cancel {
    background: #FFFFFF;
    color: #555;
    border-color: #ccc;
}
.uks-family-list-actions .uks-family-decline:hover,
.uks-family-list-actions .uks-family-cancel:hover {
    background: #FAFAFA;
    border-color: #888;
    color: #031B83;
}
.uks-family-list-actions .uks-family-revoke {
    background: #FFFFFF;
    color: #C41C1C;
    border-color: #C41C1C;
}
.uks-family-list-actions .uks-family-revoke:hover { background: #C41C1C; color: #FFFFFF; }
/* end of 38.2 */

/* 38.3 Attestation tickbox (only on incoming pending rows) */
.uks-family-attestation {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin-top: 10px;
    padding: 10px 14px;
    background: #FFFBE6;
    border: 2px solid #CC9900;
    border-radius: 10px;
    cursor: pointer;
    font-size: 13px;
    line-height: 1.45;
    color: #031B83;
}
.uks-family-attestation input[type="checkbox"] {
    margin: 3px 0 0 0;
    accent-color: #CC9900;
    width: 18px;
    height: 18px;
    flex-shrink: 0;
}
.uks-family-attestation:has(input:checked) {
    background: #FFF6CC;
}
/* end of 38.3 */

/* 38.4 Mobile */
@media (max-width: 540px) {
    .uks-family-list-row { flex-direction: column; align-items: stretch; }
    .uks-family-list-body { min-width: 0; }
    .uks-family-list-actions { flex-direction: row; min-width: 0; }
    .uks-family-list-actions button { flex: 1; }
}
/* end of 38.4 */

/* end of 38 */


/* ============================================================================
   39. SECTION: Peer Reviews settings page (S84 — A10 / D136)
   Pending review prompts surfaced as a vertical stack of cards in the
   Reviews sub-tab inside /settings/. Each card has a sigil + name + event,
   5-star radio row, qualifier tickbox grid (positives + negatives styled
   distinctly), optional notes textarea, Skip + Submit actions.
   ============================================================================ */

/* 39.1 Wrapper */
.uks-reviews-settings {
    max-width: 760px;
    margin: 0 auto;
    padding: 12px 0 32px;
    font-family: 'Nunito Sans', sans-serif;
    color: #031B83;
}
.uks-reviews-heading {
    font-family: Montserrat, sans-serif;
    font-size: 22px;
    font-weight: 700;
    color: #031B83;
    margin: 0 0 8px;
    text-align: center;
}
.uks-reviews-intro {
    margin: 0 0 28px;
    text-align: center;
    color: #555;
    line-height: 1.55;
    font-size: 14px;
}
.uks-reviews-section-title {
    font-family: Montserrat, sans-serif;
    font-size: 14px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #031B83;
    margin: 24px 0 12px;
    padding-bottom: 6px;
    border-bottom: 2px solid #CC9900;
}
.uks-reviews-empty {
    text-align: center;
    color: #888;
    padding: 24px 16px;
    background: #FFFBE6;
    border: 2px dashed #CC9900;
    border-radius: 12px;
    margin: 0;
}
/* end of 39.1 */

/* 39.2 Card */
.uks-review-card {
    background: #FFFFFF;
    border: 2px solid #CC9900;
    border-radius: 14px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
    padding: 18px 22px 20px;
    margin-bottom: 18px;
}
.uks-review-card-head {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: 16px;
    padding-bottom: 14px;
    border-bottom: 1px dashed rgba(204, 153, 0, 0.4);
}
.uks-review-card-sigil img,
.uks-review-card-sigil .avatar {
    width: 56px;
    height: 56px;
    border-radius: 9999px;
    object-fit: cover;
    border: 2px solid #CC9900;
    background: #FFFBE6;
    display: block;
}
.uks-review-card-name {
    font-family: Montserrat, sans-serif;
    font-weight: 700;
    color: #031B83;
    font-size: 16px;
}
.uks-review-card-event {
    font-size: 13px;
    color: #555;
    margin-top: 2px;
}
.uks-review-card-event em { color: #CC9900; font-style: normal; font-weight: 700; }
/* end of 39.2 */

/* 39.3 Star rating row */
.uks-review-stars-row {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: 14px;
    flex-wrap: wrap;
}
.uks-review-stars-label {
    font-family: Montserrat, sans-serif;
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #031B83;
}
.uks-review-stars {
    display: inline-flex;
    direction: rtl;  /* hover-state cascade left from currently-hovered star */
    gap: 4px;
}
.uks-review-star-label {
    cursor: pointer;
    font-size: 28px;
    line-height: 1;
    color: #ddd;
    transition: color 0.15s;
}
.uks-review-star-label input[type="radio"] {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}
.uks-review-star-label:hover,
.uks-review-star-label:hover ~ .uks-review-star-label,
.uks-review-stars:has(input:checked) .uks-review-star-label {
    color: #CC9900;
}
/* once a star is checked, paint that and everything to its right (because rtl)
   in gold; everything to its left in light grey */
.uks-review-stars input:checked ~ .uks-review-star-label { color: #CC9900; }
.uks-review-star-label:has(input:checked) { color: #CC9900; }
.uks-review-star-label:has(input:checked) ~ .uks-review-star-label { color: #ddd; }
/* end of 39.3 */

/* 39.4 Qualifiers grid */
.uks-review-qualifiers {
    border: none;
    padding: 0;
    margin: 0 0 14px;
}
.uks-review-qualifiers-legend {
    font-family: Montserrat, sans-serif;
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #031B83;
    padding: 0;
    margin-bottom: 8px;
}
.uks-review-qualifiers-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 8px;
}
/* S168 - Rob, from his phone: "the options look like they're off brand, grey and black text/boxes".
   He was right, and MEASURED on the live form the labels computed to rgba(51,51,51,0.7) - grey #333
   at 70%, inherited because this rule never set a colour at all - against a border of #E0D9B8, a
   washed beige that is not in the palette.
   FOUR INVENTED VALUES WERE IN THIS ONE BLOCK, which Appendix A bans by name ("DO NOT INVENT PALETTE
   VARIANTS - the hex values in Part II section 1 are the SINGLE SOURCE OF TRUTH"): #E0D9B8 for the
   resting border, and #c0392b / #ffd6d6 / #721c24 for the negative state - a Flat-UI red, not this
   platform's #C41C1C.
   Replaced AT SOURCE rather than scope-bumped on top (feedback_no_new_css_replace_dont_add), and the
   resting border now matches BRAND_GUIDE section 13, which already specifies 2px solid #CC9900 for
   form controls. The structure is untouched - this is colour only. */
.uks-review-qualifier {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    border: 2px solid #CC9900;              /* was #E0D9B8 - off palette */
    border-radius: 9999px;
    cursor: pointer;
    background: #FFFFFF;
    color: #031B83;                          /* was unset, so it inherited grey #333 at 70% */
    transition: border-color 0.15s, background 0.15s;
    font-size: 13px;
}
.uks-review-qualifier:hover { border-color: #CC9900; background: #FFFBE6; }
.uks-review-qualifier input[type="checkbox"] { margin: 0; accent-color: #CC9900; }
.uks-review-qualifier:has(input:checked) {
    border-color: #031B83;                   /* D055: the chosen state inverts to navy on cream */
    background: #FFFBE6;
    color: #031B83;
    font-weight: 700;
}
.uks-review-qualifier.is-negative input[type="checkbox"] { accent-color: var(--color-error, #C41C1C); }
.uks-review-qualifier.is-negative:hover { border-color: var(--color-error, #C41C1C); background: var(--color-error-bg, rgba(196, 28, 28, 0.06)); }
.uks-review-qualifier.is-negative:has(input:checked) {
    border-color: var(--color-error, #C41C1C);
    background: var(--color-error-bg, rgba(196, 28, 28, 0.06));
    color: var(--color-error, #C41C1C);
}
/* end of 39.4 */

/* 39.5 Notes + actions */
.uks-review-notes-label {
    display: block;
    margin-bottom: 14px;
}
.uks-review-notes-label > span {
    display: block;
    font-family: Montserrat, sans-serif;
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #031B83;
    margin-bottom: 6px;
}
.uks-review-notes-label textarea {
    width: 100%;
    padding: 10px 12px;
    border: 2px solid #E0D9B8;
    border-radius: 8px;
    font-family: 'Nunito Sans', sans-serif;
    font-size: 14px;
    color: #031B83;
    background: #FFFFFF;
    resize: vertical;
}
html[data-nav="kbd"] .uks-review-notes-label textarea:focus {
    border-color: #CC9900;
    outline: none;
    box-shadow: 0 0 0 2px rgba(204, 153, 0, 0.2);
}
.uks-review-actions {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
}
.uks-review-skip-btn,
.uks-review-submit-btn {
    padding: 10px 22px;
    font-family: Montserrat, sans-serif;
    font-size: 13px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    border-radius: 8px;
    cursor: pointer;
    border: 2px solid;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.uks-review-skip-btn {
    background: #FFFFFF;
    color: #555;
    border-color: #ccc;
}
.uks-review-skip-btn:hover {
    background: #FAFAFA;
    border-color: #888;
    color: #031B83;
}
.uks-review-submit-btn {
    /* S207 05/09/26, Rob item A4: gold FILL out, light cream in with a gold border and navy text; darker cream on hover and select. */
    background: var(--color-cream, #FFFBE6);
    color: #031B83;
    border-color: #CC9900;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
}
.uks-review-submit-btn:hover:not(:disabled) {
    /* S207 05/09/26, Rob item A4: hover is the DARKER cream, not a navy invert. */
    background: var(--color-cream-hover, #FFF5CC);
    color: var(--color-navy, #031B83);
    border-color: var(--color-gold);
}
/* S222: the same three banned greys as the block button, on the peer review Submitting button
   (uksocials-peer-reviews.php:802 swaps the label to Submitting...). COMPUTED before:
   rgb(102,102,102) on rgb(204,204,204), 3.58 to 1. The colours are RESTATED for the same reason
   as the block button above: without them Seeko's broad button rule paints its own grey. These
   are S207's values, the ones Rob signed off for this button at rest. */
.uks-review-submit-btn:disabled {
    background: var(--color-cream, #FFFBE6) !important;
    color: #031B83 !important;
    border-color: #CC9900 !important;
    opacity: 1;
    cursor: not-allowed;
    box-shadow: none;
}
.uks-review-error {
    margin-top: 12px;
    padding: 10px 14px;
    background: #f8d7da;
    border-radius: 8px;
    color: #721c24;
    font-size: 13px;
}
/* end of 39.5 */

/* end of 39 */


/* ============================================================================
   40. SECTION: A12 Reputation widget — 5-star + awarded badge stack
   (S84 — A12 / D137)
   Public profile reputation surface. Reads the public-safe aggregate from
   uks_peer_reviews_get_aggregate(); below the 3-review floor shows a
   "building reputation" empty state. Above the floor: 5-star numeric
   rating with a CSS-overlay fill technique (no half-star image) + up to
   6 awarded badge pills below.
   ============================================================================ */

/* 40.1 Wrapper */
.reputation-widget {
    font-family: 'Nunito Sans', sans-serif;
    color: #031B83;
    text-align: center;
    padding: 8px 4px;
}
.reputation-widget-empty .reputation-empty-text {
    margin: 16px auto 8px;
    font-size: 13px;
    color: #888;
    line-height: 1.5;
    max-width: 240px;
}
/* end of 40.1 */

/* 40.2 5-star + numeric row */
.reputation-stars-row {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    margin-bottom: 4px;
    flex-wrap: wrap;
}
.reputation-stars {
    position: relative;
    display: inline-block;
    line-height: 1;
    font-size: 26px;
}
.reputation-stars-empty {
    color: #ddd;
    letter-spacing: 1px;
}
.reputation-stars-fill {
    position: absolute;
    top: 0;
    left: 0;
    color: #CC9900;
    overflow: hidden;
    white-space: nowrap;
    letter-spacing: 1px;
}
.reputation-numeric {
    display: inline-flex;
    align-items: baseline;
    gap: 2px;
}
.reputation-numeric-value {
    font-family: Montserrat, sans-serif;
    font-size: 22px;
    font-weight: 700;
    color: #031B83;
}
.reputation-numeric-out-of {
    font-family: Montserrat, sans-serif;
    font-size: 12px;
    font-weight: 700;
    color: #888;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.reputation-meta {
    font-size: 11px;
    color: #888;
    margin-bottom: 12px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    font-family: Montserrat, sans-serif;
    font-weight: 700;
}
/* end of 40.2 */

/* 40.3 Awarded badge stack */
.reputation-badges {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    justify-content: center;
    margin-top: 6px;
}
.reputation-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background: #FFFBE6;
    border: 2px solid #CC9900;
    border-radius: 9999px;
    padding: 4px 10px;
    font-family: Montserrat, sans-serif;
    font-size: 11px;
    font-weight: 700;
    color: #031B83;
    text-transform: uppercase;
    letter-spacing: 0.4px;
}
.reputation-badge-label { white-space: nowrap; }
.reputation-badge-count {
    color: #CC9900;
    font-size: 10px;
}
/* end of 40.3 */

/* end of 40 */

/* ============================================================================
   41. SECTION: Sidenav rebuild (S86-002, D148)
   New BEM-style sidenav matching the new account-page design system. Applied
   globally across all member-area pages. The outer wrapper carries both the
   legacy `.dashboard-sidenav` class (for grid-layout wiring in profile-editor.css
   §15) AND the new `.sidenav` class (for the visual styling below). Each item
   carries both `.sidenav-item` (so dashboard-ajax-nav.js still finds them) AND
   `.sidenav__item` (for the new styling). Same dual-class trick on labels and
   badges. Old `.sidenav-item / .sidenav-label / .sidenav-badge` rules in
   profile-editor.css §15.2 are now dead but preserved as a safety net (will
   be cleaned up in a later sweep).
   ============================================================================ */

/* 41.0 Scroll-cue base — hidden at desktop, shown only at narrow viewports (the @media / @container 1023px blocks below switch it to flex). Verbatim from design styles.css:375. */
.sidenav__scroll-cue { display: none; }

/* 41.1 Outer container — visual styling. Layout/sticky/grid handled by .dashboard-sidenav rules in profile-editor.css §15.2.1 */
.sidenav {
    background: var(--color-surface);
    border: 2px solid var(--color-gold);
    border-radius: var(--radius-md);
    padding: var(--sp-md) 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
    position: sticky;
    top: var(--sp-lg);
    align-self: start;
    box-shadow: var(--shadow-sm);
}
/* end of 41.1 */

/* 41.2 Group wrapper — flex column of items, slight inset padding so active-item border doesn't kiss the outer border */
.sidenav__group {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 0 var(--sp-sm);
}
/* end of 41.2 */

/* 41.3 Divider between Group 1 and Group 2 */
.sidenav__divider {
    height: 1px;
    background: var(--color-border);
    margin: var(--sp-sm) var(--sp-md);
}
/* end of 41.3 */

/* 41.4 Item — flex row of glyph + label + (optional) badge */
.sidenav__item {
    display: flex;
    align-items: center;
    gap: 8px; /* S210: 27px glyph column + 8px = the 35px the labels already started at */
    /* -1px on each side to compensate for the always-present 1px border so
       active and inactive items have identical outer dimensions.
       S210 06/09/26, Rob: the row is 47px, an odd number, so it has a TRUE middle pixel to centre
       on; at 46px the middle fell between two pixels and nothing could sit on it. His structure,
       and it is symmetrical: 1px border, 11px padding, a 23px content area, 11px padding, 1px
       border. The content area is the odd one, so its middle is its own 12th line, and the space
       above the content is identical to the space below it. */
    height: 47px;
    padding: 11px calc(var(--sp-md) - 1px) !important;
    border-radius: 10px;
    color: var(--color-navy);
    font-weight: 600 !important;
    font-size: 15px;
    line-height: 1 !important;
    transition: background var(--duration-fast) var(--ease-out),
                border-color var(--duration-fast) var(--ease-out),
                box-shadow var(--duration-fast) var(--ease-out),
                color var(--duration-fast) var(--ease-out);
    cursor: pointer;
    /* Transparent border held at all times so adding the gold border on
       active doesn't shift the layout. */
    border: 1px solid transparent;
    background: transparent;
    text-align: left;
    width: 100%;
    font-family: var(--font-body);
    text-decoration: none;
}
/* Canonical dropdown-style hover — cream bg + gold border + navy text. Per
   Rob 28/06/26: the previous surface-raised grey + near-black text (from
   profile-editor.css `.sidenav-item:hover`) was off-brand. !important on
   bg + border + color beats profile-editor.css (same specificity, later in
   the cascade order). Border-width forced to 1px on all four sides so the
   `.app .sidenav-item { border-left: none }` reset (line ~7871) doesn't
   leave the left edge missing. The 1px transparent border at rest keeps
   layout stable.
   Wrapped in @media (hover: hover) so touch devices (mobile / tablet) don't
   sticky-hover on first tap — fixes the "tap twice to navigate" bug on the
   top-nav variant. Per Rob 28/06/26. */
@media (hover: hover) and (pointer: fine) {
    .sidenav__item:hover,
    .sidenav-item:hover {
        background: #fffbe6 !important;
        border-width: 1px !important;
        border-style: solid !important;
        border-color: #CC9900 !important;
        color: var(--color-navy) !important;
        text-decoration: none;
    }
}
/* Touch-device reset — profile-editor.css's `.sidenav-item:hover` (grey bg +
   near-black text) is unconditional, so on mobile/tablet the first tap was
   activating that hover and trapping the click (requiring a second tap to
   navigate). Force the rest-state visuals on touch so the click fires on
   the first tap. Per Rob 28/06/26. */
@media (hover: none), (pointer: coarse) {
    .sidenav__item:hover,
    .sidenav-item:hover {
        background: transparent !important;
        border-color: transparent !important;
        color: var(--color-navy) !important;
    }
}
/* end of 41.4 */

/* 41.5 Active item — raised pill: cream bg, 1px gold border, drop shadow.
   !important needed on all three: background + border beaten by .app .sidenav-item-active
   (same 0,2,0 specificity, later in file); font-weight beaten by .sidenav__item !important.
   S231 18/09/26, Rob: "the side nav in the dashboard, when an item is selected, is not light cream
   like the other menu buttons. It goes cream on hover and then you click and it goes back to that
   off white colour." It was --color-surface, plain white; it is now the same #FFFBE6 the hover
   state uses two rules above, so selecting an item keeps the colour the hover promised. */
.sidenav__item--active,
.sidenav__item--active:hover {
    background: #FFFBE6 !important;
    color: var(--color-navy);
    font-weight: 700 !important;
    border: 1px solid var(--color-gold) !important;
    border-radius: 10px;
    box-shadow: var(--shadow-gold-hover);
}
/* end of 41.5 */

/* 41.5.1 Neutralise old profile-editor.css sidenav-item left-border (the "eyebrow").
   Both old (.sidenav-item) and new (.sidenav__item) classes are on every nav item.
   .app scoping beats profile-editor's flat specificity without !important. */
.app .sidenav-item {
    /* 1px transparent at rest so the gold hover border has all four sides
       without shifting the content right by 1px. Per Rob 28/06/26. */
    border-left: 1px solid transparent;
    padding: 0;
}
.app .sidenav-item-active {
    border-left: none;
    background: transparent;
}

/* 41.6 Item label — stretches to fill remaining space between glyph and badge */
.sidenav__item-label {
    color: inherit;
    font: 600 15px/1 var(--font-body);
    letter-spacing: 0;
    text-transform: none;
    flex: 1 1 auto;
}
/* end of 41.6 */

/* 41.7 Glyph — emoji rendered via the platform's color-emoji font stack
   S86: bumped font-size from 18px → 20px after Rob flagged the Reputation
   lips emoji 👄 looking like a no-entry symbol on Windows Segoe UI Emoji at
   18px. Cross-platform emoji rendering issue (Apple's lips emoji is much
   more recognisable; Windows renders it as a small red blob with a slit).
   Larger size makes the lip-shape more legible. */
/* S210 06/09/26: the glyph box is 23px so it FILLS the rows 23px content area exactly. At 22px it
   sat half a pixel into a 23px space, which is a position no pixel can occupy, and every icon
   inherited that half pixel before its own artwork was even considered. */
/* S210 06/09/26: an icon wider than the 23px glyph box must NOT be shrunk to fit it. The Events
   ticket is a wide shape, and as a flex child it was being squeezed, which pulled its height
   down to 13.5px against the 15px every other icon measures. It now keeps its size and simply
   overhangs the box, which is invisible because the box has no background of its own. */
.sidenav__glyph svg { flex: none; }
.sidenav__glyph {
    width: 27px;
    height: 23px;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: flex-end; /* S210: right aligned so every gap to the label is the same 8px */
    font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", "Twemoji Mozilla", "EmojiOne Color", sans-serif;
    font-size: 18px;
    line-height: 1;
    /* Force colour-emoji rendering instead of black-and-white text-style */
    font-variant-emoji: emoji;
}
/* 41.7.1 and 41.7.3 DELETED 06/09/26 (S210) on Rob's instruction, along with the global
   translateY(-1px) that used to sit in 41.7 above and the runtime ink aligner in
   profile-system.php. His reasoning: two stacked rules doing the same job, on a set of icons
   that is being replaced with SVGs anyway. The sidenav is now bare so the real cause of any
   misalignment can be found and fixed at source rather than corrected after the fact. */
/* end of 41.7 */

/* ============================================================================
   40.9 SECTION: THE DEFAULT TEXT COLOUR IS NAVY, NOT GREY.
   S207 05/09/26, Rob's visual-list item A6: "There should be no grey or black text anywhere
   on the website". Asked how far it should reach, he chose navy everywhere, marketing pages
   included.

   ROOT CAUSE, measured rather than assumed: the PARENT theme's seeko-dynamic.css sets
   `body { color: #333 }`, so every element that never states its own colour inherits grey.
   That single declaration is where the platform's grey text comes from, which is why chasing
   individual components never finished the job.

   We cannot edit the parent stylesheet, so this is the override at its own root. It sets the
   INHERITED default only: anything with its own colour is untouched, and no !important is
   used, so a component can still opt out.
   ============================================================================ */
/* `html body` rather than `body`: seeko-dynamic.css loads AFTER this file, so a bare `body`
   selector loses on source order at equal specificity. Measured, not guessed - the first
   attempt used `body` and the page still computed rgb(51,51,51). Two element selectors beat
   one without needing !important, so a component can still set its own colour. */
html body {
    color: var(--color-navy, #031B83);
}

/* PMPro sets its own colour on the checkout "Processing..." line, so inheritance does not reach
   it. Rob named this one specifically: "one of the other fields, I think it was the
   registration, it says processing and that's also grey or black text." */
#pmpro_processing_message {
    color: var(--color-navy, #031B83);
}

/* ============================================================================
   40.10 SECTION: S207 05/09/26 - Rob's four public-page corrections.
   ============================================================================ */

/* 40.10.1 The "Email Form" intro box on /contact/. Measured before the change: 1000px wide,
   max-width 1000px, padding 16px 16px 20px - wider than the form beneath it and with an uneven
   bottom. Rob: "the Email form container is massive - it needs to be a lot smaller and neater
   than that, with symmetrical and uniform padding." */
/* 40.10.1.1 R3-34d (Rob, 25/09/2026): "on the thin version, the 'email form' label panel has a
   blue border but it should have a gold border, and it should be the same width as the actual
   form panel. At the moment it's wider." The navy 3px border was the page-builder's own default
   (not ours to edit at its source); scope-bumped here to the exact declaration the form panel
   itself uses (section 40.10, .organiser-apply-form: border: 1px solid #CC9900). Width: the form
   panel (.organiser-apply-form) measures, at every width, width = min(420px, 100vw - 64px) -
   verified live at 8 viewports from 412 to 1920 (348px at 412 up to the 420px cap from 484
   upward, matching to the pixel at each point). The label box previously had its own flat
   max-width: 660px, wider than the form at every width from 412 up; giving it the same formula
   the form itself resolves to makes the two match within 0.5px everywhere, not just at one
   breakpoint. */
.uksp-element-ffe5566 {
    max-width: 660px !important;   /* R3-34 (Rob 26/09): the label panel, the form and the contacts-and-picture row share one width, the row's 660px */
    width: calc(100vw - 64px) !important;
    margin-left: auto !important;
    margin-right: auto !important;
    padding: 22px !important;
    border: 1px solid #CC9900 !important;
}
/* S207 06/09/26, Rob: "There should be the same padding between the bottom border and the bottom
   text. And the top border and the title." The box padding was already even; what was not, was the
   heading's own top margin and the subtitle's bottom margin inside it. Zero both so the visible
   gap is the box padding on all four sides. */
.uksp-element-ffe5566 > * { margin-top: 0 !important; margin-bottom: 0 !important; }
.uksp-element-ffe5566 .uksp-heading-title { margin: 0 0 10px !important; }
.uksp-element-ffe5566 p:last-child { margin-bottom: 0 !important; }

/* F: the contact form sat on a white panel with a black drop shadow, inside the off-white page,
   with the gold-bordered form inside that - three layers. Rob wants two: the page, then the form
   carrying its own shadow, in gold rather than black. */
.contact-form-wrapper {
    background: transparent !important;
    box-shadow: none !important;
    padding: 0 !important;
}
.contact-form-wrapper .organiser-apply-form {
    background: #FFFFFF !important;
    border: 1px solid #CC9900 !important;
    border-radius: 12px !important;
    padding: 24px 28px !important;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.28) !important;
}
/* FF02-13: The shared About/Contact form reads centred, including the textarea
   placeholder, without changing the form structure. */
.contact-form-wrapper .organiser-apply-form label,
.contact-form-wrapper .organiser-apply-form input,
.contact-form-wrapper .organiser-apply-form textarea {
    text-align: center !important;
}
.contact-form-wrapper .organiser-apply-form label {
    display: block !important;
    font-family: var(--font-heading), 'Montserrat', sans-serif !important;
    font-weight: 700 !important;
    transform: translateY(-2px);
}
body.page-id-926 .contact-form-wrapper .organiser-apply-form input,
body.page-id-926 .contact-form-wrapper .organiser-apply-form textarea,
body.page-id-926 .contact-form-wrapper .organiser-apply-form select,
body.page-id-926 .contact-form-wrapper .organiser-apply-form .ev-dd__btn {
    border: 2px solid var(--color-gold) !important;
    box-shadow: none !important;
    text-align: center !important;
}
.contact-form-wrapper .organiser-apply-form select option,
.contact-form-wrapper .organiser-apply-form .ev-dd__opt {
    border-width: 1px !important;
}
.contact-form-wrapper .organiser-apply-form input::placeholder,
.contact-form-wrapper .organiser-apply-form textarea::placeholder {
    text-align: center !important;
}

/* 40.10.2 Blog posts read centred, like the rest of the site. Measured: the entry title was
   already centred but every paragraph computed text-align:left, which is what Rob could see.
   Scoped to single posts and the blog index so it cannot reach app surfaces. */
body.single-post .entry-content,
body.single-post .entry-content p,
body.single-post .entry-content li,
body.single-post .entry-content h2,
body.single-post .entry-content h3,
body.blog .entry-content,
body.blog .entry-content p {
    text-align: center;
}

/* 40.10.3 The blog index had no visible heading and its cards sat in a thin band with a large
   empty space beneath. Give the page its title back and let the grid breathe. */
/* Measured: the h1.page-title exists on /blog/ but computes display:none, which is why the page
   had no heading at all. It is put back, not invented. */
body.blog h1.page-title,
body.blog .page-title,
body.blog .entry-title--archive {
    display: block !important;
    text-align: center;
    font-size: 34px;
    color: var(--color-navy, #031B83);
    margin: 8px auto 28px;
    text-shadow: 0 2px 3px rgba(3, 27, 131, 0.22);
}
body.blog .site-main,
body.blog .content-area {
    padding-bottom: 24px;
}

/* G: the category menu across the top of the blog. Measured: every tag is .btn-tag with a flat
   #CC9900 fill, and the hovered one turned bright yellow, which is what Rob saw on HEALTH. They
   now use the same cream and gold button as the rest of the site, laid out in a tidy centred row.
   S207 06/09/26. */
body.blog .meta-category,
body.single-post .meta-category {
    display: flex !important;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px;
    margin: 0 auto 26px;
    max-width: 900px;
}
body.blog .meta-category .btn-tag,
body.single-post .meta-category .btn-tag,
body.blog a.btn-tag,
body.single-post a.btn-tag {
    background: var(--color-cream, #FFFBE6) !important;
    color: var(--color-navy, #031B83) !important;
    border: 1.5px solid var(--color-gold, #CC9900) !important;
    border-radius: 9999px !important;
    padding: 5px 14px !important;
    font-size: 12px !important;
    line-height: 1.4 !important;
    text-transform: uppercase;
    letter-spacing: .04em;
    box-shadow: var(--shadow-gold-hover) !important;
}
body.blog .meta-category .btn-tag:hover,
body.single-post .meta-category .btn-tag:hover,
body.blog a.btn-tag:hover,
body.single-post a.btn-tag:hover {
    background: var(--color-cream-hover, #FFF5CC) !important;
    color: var(--color-navy, #031B83) !important;
    border-color: var(--color-gold, #CC9900) !important;
}
/* D-651 (S235 FIXER-SHADOWS-3, 24/09/26): pressed = cream-hover, no shadow. */
body.blog .meta-category .btn-tag:active,
body.single-post .meta-category .btn-tag:active,
body.blog a.btn-tag:active,
body.single-post a.btn-tag:active {
    background: var(--color-cream-hover, #FFF5CC) !important;
    box-shadow: none !important;
}

/* H: the blog cards. Measured before: white with a 1px rgba(3,27,131,.06) hairline, a soft navy
   shadow and a pale blue-green blob in the corner. Rob: gold border, gold shadow, white
   background, navy text, and scrap the blob. S207 06/09/26. */
body.blog .post-card {
    background: #FFFFFF !important;
    border: 1.5px solid var(--color-gold, #CC9900) !important;
    border-radius: 14px !important;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.28) !important;
    overflow: hidden;
}
body.blog .post-card::before,
body.blog .post-card::after {
    display: none !important;          /* the light blue-green corner blob */
}
body.blog .post-card,
body.blog .post-card a,
body.blog .post-card p,
body.blog .post-card h2,
body.blog .post-card h3 {
    color: var(--color-navy, #031B83) !important;
}
/* The four cards sat in a thin band with a tall empty space beneath. Centre the grid and let the
   cards fill the row evenly. */
body.blog .site-main > .row,
body.blog .content-area > .row {
    justify-content: center;
}

/* Category archives use the same title, cards and category pills as the Blog index. */
body.category h1.page-title,
body.category .page-title {
    display: block !important;
    text-align: center !important;
    font-size: 34px !important;
    color: #031B83 !important;
    margin: 8px auto 28px !important;
    text-shadow: 0 2px 3px rgba(3, 27, 131, 0.22) !important;
}
body.category .post-card {
    background: #FFFFFF !important;
    border: 1.5px solid #CC9900 !important;
    border-radius: 14px !important;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.28) !important;
    overflow: hidden !important;
}
body.category .post-card::before,
body.category .post-card::after {
    display: none !important;
}
body.category .post-card,
body.category .post-card a,
body.category .post-card p,
body.category .post-card h2,
body.category .post-card h3 {
    color: #031B83 !important;
}
body.category .meta-category {
    display: flex !important;
    flex-wrap: wrap !important;
    justify-content: center !important;
    gap: 8px !important;
    margin: 0 auto 26px !important;
    max-width: 900px !important;
}
body.category .meta-category .btn-tag,
body.category a.btn-tag {
    background: #FFFBE6 !important;
    color: #031B83 !important;
    border: 1.5px solid #CC9900 !important;
    border-radius: 9999px !important;
    padding: 5px 14px !important;
    font-size: 12px !important;
    line-height: 1.4 !important;
    text-transform: uppercase !important;
    letter-spacing: 0.04em !important;
    box-shadow: none !important;
}

/* R3-35 and R3-36 (Rob, 24/09/2026, round 3 items 35 and 36; first asked in round 2, item 9).
   The single blog post. */
/* R3-35: the post title takes the SAME drop shadow as every other page title. The value is the
   main page title rule's ("THE MAIN PAGE TITLES TAKE THE EVENT PAGE'S TITLE TREATMENT", S231,
   further down), measured on the /events/ title as rgba(3,27,131,.18) 0 4px 6px,
   rgba(3,27,131,.12) 0 2px 4px. No other rule sets a shadow on this title. */
body.single-post .entry-header .entry-title {
    text-shadow: 0 4px 6px rgba(3,27,131,.18), 0 2px 4px rgba(3,27,131,.12);
    /* R3-35b (Rob 25/09: "put a gold underline under the title like on the other pages"): the same
       gold rule the main page titles carry (S231 block further down), hugging the words and centred. */
    display: table !important;
    width: fit-content !important;
    max-width: 100%;
    margin-left: auto;
    margin-right: auto;
    padding-bottom: 8px;
    border-bottom: 2px solid var(--color-gold);
}
/* R3-35: the category pills print at the foot of the article now, four at most
   (mu-plugins/uksocials-blog-categories.php). Their look and their 8px gap are the
   body.single-post .meta-category rules above; this only parts the group from the last paragraph. */
body.single-post .meta-category.meta-category--foot {
    margin-top: 32px;
}
/* R3-36: one page colour down the whole post. The parent theme paints the Related Articles band
   white (theme-static.css, #fff) between the off-white article and the off-white comments, so the
   page changed colour half way down. It shows the page background now, like everything round it.
   body lifts it past the theme's rule of equal weight, which loads after this file. */
body .related-articles {
    background: transparent;
}
/* R3-36: the comment form centred and stacked: the picture, Leave a reply, "Logged in as <name>."
   on its own row, "Log out?" on the row below, the box, then the button. The ids beat the parent
   theme's row layout (.comment-respond is a flex row in theme-static.css, loaded after this file). */
#respond {
    flex-direction: column;
    align-items: center;
    text-align: center;
}
#respond > .avatar {
    margin: 0 0 16px;
}
#respond #commentform {
    width: 100%;
}
/* R3-36b 25/09/2026 (Rob: "the text field should have a gold border, not grey. Same with
   the little marker on the bottom right corner, it should be gold"). The comment textarea
   carried no border rule in this theme, so it showed the parent theme's grey default; the
   #commentform id beats that on specificity. Focus state repeats the same gold, no grey ring.
   Value copied from the platform's other gold-bordered inputs (D-641's connection-code field,
   .st-connect-card__code, 2px solid var(--color-gold)). */
#commentform textarea {
    border: 2px solid var(--color-gold);
}
#commentform textarea:focus {
    border-color: var(--color-gold);
    outline: none;
}
/* R3-36b: the resize grip, two diagonal gold hairlines on a transparent field, 12px by 12px
   (an inline SVG data URI, no file), the same technique as the message composer's own resizer
   (.msg-compose-card .form-textarea::-webkit-resizer above) with the gold token in place of
   navy. The bare `textarea` type selector covers every textarea in this form, not just #comment. */
#commentform textarea::-webkit-resizer {
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M11 1 L1 11 M11 6 L6 11' stroke='%23CC9900' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat center / 12px 12px;
    background-color: transparent;
}
#respond .logged-in-as a[href*="action=logout"] {
    display: block;
    width: fit-content;
    margin: 0 auto;
}
/* R3-36: Post comment is the standard button (D-640): cream, gold border, 10px corners, navy text
   and the gold shadow at rest; pressed is the darker cream with no shadow, and it goes straight back
   when the press ends, so it is never left dark. Shape and type are the canonical .btn's (42.8).
   The ids beat seeko-dynamic.css's gold-filled .btn-primary and its dark gold hover with white text,
   which load after this file; the first rule covers :hover too, so a tap on a phone cannot leave
   that dark gold behind. */
#commentform #submit,
#commentform #submit:hover {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--color-cream);
    border: 2px solid var(--color-gold);
    border-radius: 10px;
    color: var(--color-navy);
    box-shadow: var(--shadow-gold-hover);
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 14px;
    line-height: 1;
    padding: 10.5px 24px;
    text-transform: none;
    letter-spacing: normal;
    cursor: pointer;
}
@media (hover: hover) {
    #commentform #submit:hover {
        background: var(--color-cream-hover);
    }
}
#commentform #submit:active {
    background: var(--color-cream-hover);
    box-shadow: none;
}

/* 41.8 Badge — small circular cream pill with gold border + navy text */
/* ONE rule for the cream badge. The double-class selector is carried here rather than in a
   second rule underneath: profile-editor.css loads after this file on the customise page and
   its legacy `.sidenav-badge` would otherwise win on equal specificity. Rob, 05/09/26: "CSS
   should not be stacked from decision to decision, there should be only one rule." */
.sidenav__badge,
.sidenav-badge.sidenav__badge {
    margin-left: auto !important;
    background: var(--color-cream) !important;
    color: var(--color-navy);
    border: 1.5px solid var(--color-gold) !important;
    border-bottom-width: 1.5px !important;
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 11px;
    width: 21px;
    height: 21px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    line-height: 1 !important;
    padding-top: 0 !important;
}
/* THE ONE RULE FOR THE GREEN TICK BADGE. D-181 (S147, Rob): notification badges are a boolean
   GREEN TICK, not a numeric count - it just says "you have something new". Canonical success
   styling, the same as the attendance-privacy toggle: light-green fill, dark-green ring,
   dark-green tick. Nothing else in this file colours this badge; if the green ever changes it
   changes here and only here. */
.sidenav-badge--tick.sidenav__badge {
    background: var(--color-success-bg) !important;
    border: 1.5px solid var(--color-success) !important;
    color: var(--color-success) !important;
    font-size: 13px;
    font-weight: 700;
    /* S207 04/09/26 - the tick is now an SVG (profile-system.php 0.1.4i), not the bare
       character U+2713, so the S198 padding hack is gone with it. That hack existed only
       because a bare text node cannot be transformed and the vertical axis quantised to
       whole pixels, stalling the ink 0.47px low; the same note named "replace the character
       with a brand SVG" as the way out. Flex centring now places the SVG box, and the ink is
       centred inside that box by the path geometry. Was `padding: 2px 0 0 1px`. */
    padding: 0 !important;
}
/* end of 41.8 */

/* end of 41 */

/* ============================================================================
   42. SECTION: Account-page design system — workspace, section-nav, cards, buttons,
       forms, toggles, modals, tier-hero, methods, invoices, danger-zone (S86-003 D148)
   New canonical components ported from new account page design/design/styles.css.
   These are global primitives — applied wherever the markup uses them, not just
   /account/. Container queries from the prototype have been converted to standard
   @media queries (the prototype's `viewport-frame { container-type: inline-size }`
   wrapper isn't shipped to production).
   ============================================================================ */

/* =============================================================================
   PLACEHOLDER COLOUR - ONE RULE FOR THE WHOLE PLATFORM (S213 item 50, 08/09/26)
   =============================================================================
   Rob: "that input field placeholder text looks an awful lot like grey to me. Please just stop
   doing grey. Any way you see grey placeholder text just make it blue."

   WHY IT KEPT COMING BACK. Seeko ships
   `input:not([type])::-webkit-input-placeholder { color: rgb(154,154,154) }` at a specificity of
   (0,1,1). Almost every placeholder rule in this theme is written `.some-class::placeholder`,
   which is (0,1,0) and LOSES. So fields that were authored navy have been painting Seeko's grey
   all along, which is why the same fault has been "fixed" repeatedly and keeps reappearing.

   THE FIX. One rule, at (0,2,1), which outranks Seeko without !important and without touching
   every field. Navy at 65%: measured against the alternatives on a real form, 40% renders
   rgb(154,164,205) and reads grey, 55% is still soft, 65% reads unmistakably blue while staying
   clearly lighter than typed text. Spelled both ways because Chrome treats the webkit alias as
   the same pseudo-element.

   NOT COVERED, deliberately: the five interstitial walls echo their own document and never load
   this stylesheet (L-271), so any placeholder there needs its own inline rule.
   ========================================================================== */
input:not([type="hidden"]):not([type="submit"])::placeholder,
input:not([type="hidden"]):not([type="submit"])::-webkit-input-placeholder,
textarea:not([readonly]):not([disabled])::placeholder,
textarea:not([readonly]):not([disabled])::-webkit-input-placeholder {
  color: rgba(3, 27, 131, 0.65);
  opacity: 1;
}

/* =============================================================================
   42.0 — APP-SHELL LAYOUT (single-layout policy for sidenav pages)
   =============================================================================
   ARCHITECTURE NOTE (S89, 10/05/26):
   Every sidenav-driven dashboard page on this site uses ONE layout system: the
   design-agent's `.app` shell. The shell is a single child of .col-inner; it
   contains its own internal sidenav (left) + workspace (right) two-column grid.
   The OLD layout (sidenav as direct child of .col-inner, content as a sibling)
   has been retired for every sidenav page — it remains only on the customise
   page (/customise/), which is the widget editor and never appears in the
   sidenav. See profile-editor.css §15.4 for the customise-only legacy layout.

   The rules below scope to `body.profile-dashboard-active:not(.profile-editor-active)`
   so they apply to every sidenav page (account, attendance, invites, messages,
   settings, etc.) and NEVER to customise.

   When the site is rebuilt from scratch, copy this exact policy: ONE layout for
   every sidenav page (.app + sidenav + workspace), customise as its own thing.
   Do NOT reintroduce a parent grid on the BP wrapper.
   ============================================================================= */

/* 42.0 Container query root — `.app`'s internal @container vp queries (§42.15)
   need a container ancestor at full viewport width. #item-body is the closest
   ancestor that always spans the viewport; .app itself is too narrow because
   BP/Seeko wrappers cap it at ~978px. Placing the cq root on .app caused
   @container vp (max-width:1023px) to fire permanently, collapsing the two-col
   layout (S88 finding). */
body.profile-dashboard-active:not(.profile-editor-active) #item-body {
    container-type: inline-size;
    container-name: vp;
}

/* 42.0a KNOWN OFFSET — every `@container vp` breakpoint fires at a WIDER viewport
   than its nominal px, because the §42.0 comment above is wrong: #item-body does
   NOT "always span the viewport". §42.0.4 caps the dashboard at 90vw and #item-body
   sits inside that cap, so a container query measures #item-body (narrower than the
   viewport), not the viewport itself:
     • >=1024: #item-body = 0.9 x (viewport - scrollbar). So `@container vp
       (max-width:1023px)` (the §42.15 two-col -> top-nav collapse) fires at
       viewport ~1151, not 1024  (1023 / 0.9 + ~15px scrollbar).
     • <=1023: the 90vw cap drops, so #item-body = viewport - ~15px scrollbar. So the
       (max-width:599px / 600px / 767px) mobile breakpoints fire ~15px wide — e.g.
       the 599 mobile switch actually happens at viewport ~615.
   DECISION (Rob, 03/06/26): the sub-1024 offset (615-vs-599) is LEFT AS-IS on purpose
   — it's only ~15px, purely cosmetic, and 0px on overlay-scrollbar systems (Mac). The
   real fix for the whole family is to key these off the TRUE viewport, i.e. swap
   `@container vp (max-width:X)` -> `@media (max-width:X)`. That is deferred to the site
   rewrite so we don't re-architect the signed-off 90vw layout now. Future agent: at
   rewrite time, convert these vp container-queries to @media and every breakpoint
   (1151->1024, 615->599) lands on its exact px. */

/* 42.0.1 App shell — two-column grid that wraps sidenav + workspace.
   Verbatim from design styles.css:359-369. No !important, no scope-bumps.
   This works at every breakpoint because the legacy .col-inner grid has been
   removed from sidenav pages (see profile-editor.css §15 for the customise-only
   exception). */
.app {
    display: grid;
    grid-template-columns: 220px 1fr;
    min-height: auto;
    padding: 0 calc(var(--sp-2xl) + 20px) var(--sp-3xl);
    gap: var(--sp-2xl);
    align-items: start;
}
/* end of 42.0.1 */

/* 42.0.2 Unblock sticky — Seeko/BP wrappers use `overflow: hidden auto`
   (especially at narrow widths on .col-inner / .row) which establishes a
   scroll formatting context and kills `position: sticky` on .sidenav AND
   .section-nav-bar before they can reach the html viewport. `overflow: clip`
   clips visually but does NOT establish a scroll formatting context, so
   sticky propagates through it.
   See LB-059 (S88) and LB-061 (S89) — sticky failed at 600/360 in S88
   because these ancestors hadn't been covered. */
body.profile-dashboard-active:not(.profile-editor-active) .container,
body.profile-dashboard-active:not(.profile-editor-active) .bp-member-layout {
    /* Same asymmetric pattern as .row / #item-body below — horizontal clip keeps
       sticky working (defeats BP/Seeko `overflow: hidden auto`), vertical visible
       lets absolute popovers (visibility dropdown on the last card) extend past
       the container's bottom edge instead of being clipped at the footer line. */
    overflow-x: clip !important;
    overflow-y: visible !important;
}
/* `.col-inner` / `.row` / `#item-body` need asymmetric overflow: clip horizontally
   (defeats BP/Seeko's `overflow: hidden auto` that blocks sticky), visible
   vertically (so content shifted up by §42.0.4c's negative margin-top isn't
   clipped at the top — keeps sidenav's top border visible). */
body.profile-dashboard-active:not(.profile-editor-active) .col-inner,
body.profile-dashboard-active:not(.profile-editor-active) .row,
body.profile-dashboard-active:not(.profile-editor-active) #item-body {
    overflow-x: clip !important;
    overflow-y: visible !important;
}
body.profile-dashboard-active:not(.profile-editor-active) {
    /* Match the same pattern as .row / #item-body above — horizontal clip prevents
       sideways scroll, vertical visible lets absolute-positioned popovers (e.g.
       the visibility dropdown on the last card) extend past the body bottom edge
       instead of being clipped at the footer line. */
    overflow-x: clip !important;
    overflow-y: visible !important;
}
/* end of 42.0.2 */

/* 42.0.3 Full-width BP layout — two nested .container elements cap the layout:
   (1) .bp-member-layout > .container (Seeko outer) — max-width ~1080px at 1248px vp
   (2) #item-body > .container (BP inner) — also constrained
   Child selectors throughout so we don't widen unrelated inner layout columns. */
body.profile-dashboard-active:not(.profile-editor-active) .bp-member-layout > .container {
    max-width: 100% !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
}
body.profile-dashboard-active:not(.profile-editor-active) .bp-member-layout > .container > .row {
    margin-left: 0 !important;
    margin-right: 0 !important;
}
body.profile-dashboard-active:not(.profile-editor-active) .bp-member-layout > .container > .row > .col-12 {
    padding-left: 0 !important;
    padding-right: 0 !important;
    max-width: 100% !important;
    width: 100% !important;
}
body.profile-dashboard-active:not(.profile-editor-active) #item-body > .container {
    max-width: 100% !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
}
body.profile-dashboard-active:not(.profile-editor-active) #item-body > .container > .row {
    margin-left: 0 !important;
    margin-right: 0 !important;
}
body.profile-dashboard-active:not(.profile-editor-active) #item-body > .container > .row > .col-12 {
    padding-left: 0 !important;
    padding-right: 0 !important;
    max-width: 100% !important;
    width: 100% !important;
}
body.profile-dashboard-active:not(.profile-editor-active) #item-body > .container > .row > .col-12 > .col-inner {
    max-width: 100% !important;
    width: 100% !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
}
/* S230 dashboard row 57: BuddyPress adds `padding-bottom: 2rem` to
   `#item-body` (36px at the site's 18px root size). It is empty space below
   the dashboard workspace, not part of the page design. Remove that padding
   on dashboard pages only; the deliberate workspace/footer rhythm remains. */
body.profile-dashboard-active:not(.profile-editor-active) #item-body {
    padding-bottom: 0 !important;
}
/* end of 42.0.3 */

/* 42.0.4 Cap sidenav-page chrome to 90vw at >=1024 (Rob spec, signed off at 1920).
   Below 1024 the cap drops so narrow screens stay full-bleed. */
@media (min-width: 1024px) {
    body.profile-dashboard-active:not(.profile-editor-active) .bp-member-layout {
        max-width: 90vw !important;
        margin-inline: auto !important;
    }
}
/* end of 42.0.4 */

/* 42.0.5 Defeat BuddyPress Nouveau's full-bleed breakout at <=1149.9px.
   BP Nouveau's buddypress.min.css ships (stock, neither we nor WP authored the px):
     @media (min-width:576px) and (max-width:1149.9px){
       #item-nav,#item-body{ margin-left:calc(50% - 50vw); margin-right:calc(50% - 50vw);
                             width:auto; max-width:1000% } }
   The margin-inline breakout yanks #item-body OUT of the §42.0.4 .bp-member-layout
   90vw cap, so dashboard content jumps from 90vw to full-bleed exactly at 1150 — and
   because #item-body is the §42.0 container-query root, every @container vp reading
   lurches at the same point. (Elementor independently switches the header at its own
   1150px breakpoint in frontend.min.css — that's a separate Elementor SETTING, not CSS.)
   Re-cap #item-body (and formerly #item-nav) to its parent for the dashboard at >=1024 so the 1280
   layout holds unchanged down to 1024. Stops at 1024 because below that the §42.0.4 cap
   drops and full-bleed is the intended design. Scoped to the dashboard so public BP
   directories keep BP's stock full-bleed. */
/* S219 (VC 06): from 768, and on the customise editor too. The parent theme's BuddyPress breakout
   (576 to 1149.9) pushed #item-body 22.5px past each side of an iPad screen, so the editor toolbar
   measured 798px in a 768 screen. */
@media (min-width: 768px) {
    /* X05 (S238): the #item-nav selector that sat here went with the element (no longer printed). */
    body.profile-dashboard-active #item-body {
        margin-left: 0 !important;
        margin-right: 0 !important;
        max-width: 100% !important;
    }
}
/* end of 42.0.5 */

/* 42.0.4a Image banner — gold border + rounded corners, brand-standard.
   Targets the BP cover-image element directly. ID specificity (1,2,0) plus
   `!important` defeats the legacy `profile-editor.css §16.4.1`
   `#item-header-cover-image.profile-cover-image { border-radius: 0 !important }`
   that fires at @media ≤639 (LB-060). Fires on owner-dashboard and on
   public-profile views; excludes customise where the banner has its own
   edit chrome treatment. */
body.profile-dashboard-active #item-header-cover-image.profile-cover-image,
body.profile-public-active #item-header-cover-image.profile-cover-image {
    border: 2px solid var(--color-gold) !important;
    border-radius: var(--radius-md, 16px) !important;
}
/* end of 42.0.4a */

/* 42.0.4b Image banner gutter at ≤1023 — match the sidenav (top nav) width.
   The sidenav inherits `.app`'s side padding (sp-md / sp-lg / 5cqw per
   breakpoint). Two-step alignment:
   (a) zero out #item-header's own padding-inline so the banner's gutters are
       measured from the viewport edge, not from inset content;
   (b) banner gets the same margin-inline as .app's padding at each breakpoint.
   Result: banner.left = sidenav.left, banner.width = sidenav.width. */
@media (max-width: 1023px) {
    body.profile-dashboard-active:not(.profile-editor-active) #item-header {
        padding-left: 0 !important;
        padding-right: 0 !important;
    }
    body.profile-dashboard-active:not(.profile-editor-active) #item-header-cover-image.profile-cover-image {
        margin-left: var(--sp-md) !important;
        margin-right: var(--sp-md) !important;
        width: calc(100% - (var(--sp-md) * 2)) !important;
    }
}
@media (max-width: 767px) {
    body.profile-dashboard-active:not(.profile-editor-active) #item-header-cover-image.profile-cover-image {
        margin-left: var(--sp-lg) !important;
        margin-right: var(--sp-lg) !important;
        width: calc(100% - (var(--sp-lg) * 2)) !important;
    }
}
@media (max-width: 599px) {
    body.profile-dashboard-active:not(.profile-editor-active) #item-header-cover-image.profile-cover-image {
        margin-left: 5vw !important;
        margin-right: 5vw !important;
        width: 90vw !important;
    }
}
/* end of 42.0.4b */

/* 42.0.4c Tighten gap between BP cover-image-header and .app top at ≤1023.
   Natural gap is ~36px. -10px keeps it tighter (gap drops to ~26px) while
   leaving comfortable clearance below the .profile-identity-bar's bottom edge
   so the sidenav's 2px gold top border stays visible.
   !important needed to defeat a legacy
   `body.profile-dashboard-active #item-body .col-inner > :not(...) { margin-top: 0 }`
   rule (specificity 1,5,1) elsewhere in the cascade. */
@media (max-width: 1023px) {
    body.profile-dashboard-active:not(.profile-editor-active) .app {
        margin-top: -10px !important;
    }
}
/* end of 42.0.4c */

/* 42.0.4d Host pill on the top of the sigil (Rob 07/10/26, D-794, with his mock-up
   profile-07-host-pill-centred-on-sigil-rob-mockup.png: "it should be dead centre across the top of the
   sigil because it pushes the entire window down a little bit"). S245 09/10/26, row 79.
   Before: the pill was an in-flow row (.profile-badges, 24px) under the handle, so a host's side panel started 24px
   lower than everyone else's, and the pill sat 8px left of the sigil's centre at 1024 and wider (the name block is
   centred on the nav, the sigil is not) and on the page's centre at 360. Now it is out of the flow and on the sigil.
   Its own look is untouched (profile-editor.css 16.2.3.4). No rule placed it before, so this is one scoped block.
   WHERE (every number is copied or measured, none invented):
   - top 5px: Rob's mock-up, from its pixels: the banner's top border (2px thick) starts at row 50 and the pill's top row is 55, so
     the pill starts 5px below the banner's top edge. The sigil's ring starts 11px down and the pill is 24px tall, so it lies across the
     top of the ring, as in the mock-up. Measured on the live page with this block: pill top minus banner top is 5.00px at seventeen
     widths from 1920 down to 320.
   - left: the middle of the sigil, from the left edge of #cover-image-container, which becomes the pill's containing block
     once .profile-identity-inner stops being positioned (it holds no other positioned child on these pages). That is the
     banner's gutter (0 at 1024 and wider; var(--sp-md) at 1023 and below, var(--sp-lg) at 767 and below, 5vw at 599 and
     below: 42.0.4b above) plus the banner's 2px border plus the sigil's left (profile-editor.css 16.2.1.1: 67px, and 10px at
     639 and below, 16.4.2) plus half the sigil (95px; 75px at 1023 and below, 16.3.2; 55px at 639 and below, 16.4.3), so
     164px, then 144, 144, 67 and 67 on top of the gutter. translateX(-50%) centres the pill's own width on that point, so a
     longer label stays centred. Measured: the pill's centre minus the sigil's centre is 0.00px at all seventeen.
   - z-index 6: above the banner (3). The sigil's own 5 is inside the banner's stacking context, so a pill that is not
     inside the banner needs its own number above the banner's.
   Customise, the public profile and every other page that prints this header are untouched: the dashboard body class with
   :not(.profile-editor-active) is the scope 42.0.4b and 42.0.4c use. */
body.profile-dashboard-active:not(.profile-editor-active) .profile-identity-inner {
    position: static;
}
body.profile-dashboard-active:not(.profile-editor-active) .profile-badges .profile-badge-host {
    position: absolute;
    top: 5px;
    left: 164px;
    transform: translateX(-50%);
    z-index: 6;
}
@media (max-width: 1023px) {
    body.profile-dashboard-active:not(.profile-editor-active) .profile-badges .profile-badge-host {
        left: calc(var(--sp-md) + 144px);
    }
}
@media (max-width: 767px) {
    body.profile-dashboard-active:not(.profile-editor-active) .profile-badges .profile-badge-host {
        left: calc(var(--sp-lg) + 144px);
    }
}
@media (max-width: 639px) {
    body.profile-dashboard-active:not(.profile-editor-active) .profile-badges .profile-badge-host {
        left: calc(var(--sp-lg) + 67px);
    }
}
@media (max-width: 599px) {
    body.profile-dashboard-active:not(.profile-editor-active) .profile-badges .profile-badge-host {
        left: calc(5vw + 67px);
    }
}
/* end of 42.0.4d */

/* 42.0.5 Centre the LOGOUT / DASHBOARD buttons inside the top blue bar at ≤1023.
   Email (.uksp-element-3e8df955) is now hidden globally — see style.css §5.4.
   Social-links (.uksp-element-c38eb63) is hidden globally — see style.css §5.3.
   Boundary shifted 1024→1023 by VFA S90 11/05/26 to align with Seeko's hamburger
   transition at ≤1023 (also style.css §5.2). */
@media (max-width: 1023px) {
    body.profile-dashboard-active:not(.profile-editor-active) .uksp-element-5eb96116 {
        justify-content: center !important;
    }
}
/* end of 42.0.5 */

/* 42.1 Workspace */
/* max-width + auto margins ported from design reputation.css line 8 — workspace
   stays ~760px even at 1920px so cards/sections have proper proportions. */
.workspace {
    padding: 0;
    width: 100%;
    min-width: 0;
    max-width: 760px;
    margin-left: auto;
    margin-right: auto;
}
.workspace__header {
    text-align: center;
    margin-bottom: var(--sp-2xl);
}
.workspace__title {
    font-family: var(--font-heading);
    font-size: 40px;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--color-navy);
    margin-bottom: var(--sp-sm);
    line-height: 1.2;
}
.workspace__subtitle {
    font-size: 17px;
    color: var(--color-text-secondary);
    max-width: 560px;
    margin: 0 auto;
    text-wrap: pretty;
}
/* end of 42.1 */

/* 42.2 Section nav bar — sticky pill row at top of workspace.
   Verbatim from design styles.css:556-568 EXCEPT bg + mask removed in S89 per
   Rob: the bar's full-width bg + mask-image fade was painting a visible grey
   gradient strip out to the left and right of the pill at all viewport widths
   (because the bar extends past the pill's width while the pill is centered).
   Rob wants no fade left/right of the pill. Result: pill scrolls cleanly with
   no surrounding grey. The bar still wraps + centres the pill. */
/* S224 15/09/26, item 127. Rob's photo shows the Show Interest panel painting BEHIND the
   Profile / Preferences / Reputation row. The panel is inside .profile-identity-inner, which
   carries its own stacking context at z-index 2, so the bar below at z-index 10 wins whatever
   the panel itself is set to. profile-system.php records an earlier agent trying z-index 10 and
   then 999 ON THE PANEL and both still losing, for exactly this reason: a child cannot climb out
   of its parent's context. The CONTEXT is what has to move, and only while the panel is open, so
   nothing else on the page changes. 20 clears the bar's 10 with room to spare. */
.col-header:has(.interest-reasons-popover.is-open),
.profile-cover-redesign:has(.interest-reasons-popover.is-open),
.profile-identity-inner:has(.interest-reasons-popover.is-open) {
    position: relative;
    /* !important because .col-header carries z-index 4 from a rule that outranks a plain
       two-class selector, and 4 is BELOW the nav bar's 10, which is what was capping the
       whole header branch. Measured: with the branch at 4 the nav item wins the overlap. */
    z-index: 30 !important;
}
.section-nav-bar {
    position: sticky;
    top: 0;
    z-index: 10;
    margin: 0 calc(-1 * var(--sp-xl)) var(--sp-2xl);
    padding: var(--sp-md) var(--sp-xl) var(--sp-lg);
    display: flex;
    justify-content: center;
}
@media (max-width: 600px) {
    .section-nav-bar { position: static; }
}
/* My Interests: the sticky bar belongs to other dashboard pages, not here.
   Drop sticky for this page only via the page-specific .mi-nav-bar hook.
   Specificity (0,2,0) beats the base .section-nav-bar (0,1,0); with position
   static the 42.2a `top` rule is inert. Per Rob 2026-06-28. */
.my-interests .mi-nav-bar { position: static; }
/* Event Invites: same as above, sticky bar isn't needed here. Per Rob 28/06/26. */
.event-invites .ei-nav-bar { position: static; }
/* Messages: same again (Rob 10/09/26, S219): the nav stays where it is and scrolls away with the page. */
.uks-messages .section-nav-bar { position: static; }
/* Event Invites cards: +2px to the title→date gap globally so the visual
   spacing matches the rest of the card. Scoped to event-invites so Attendance
   pages (which share .att-res-card__top) stay untouched. Per Rob 28/06/26. */
.event-invites .att-res-card .att-res-card__top { gap: calc(var(--sp-xs) + 2px); }

/* 42.2a Scope-bump — clear the live site header on dashboard pages.
   Specificity (0,3,1) beats the design's `.section-nav-bar` (0,1,0) without
   `!important`. Per-breakpoint header heights are set via the
   --site-header-clear custom property; the value at each breakpoint is the
   measured live header bottom edge in CSS pixels. */
body.profile-dashboard-active:not(.profile-editor-active) {
    --site-header-clear: 158px; /* default — measured at 1024+ when email-bar is still visible */
}
@media (max-width: 1024px) {
    body.profile-dashboard-active:not(.profile-editor-active) {
        --site-header-clear: 154px; /* email widget hidden, buttons-bar + logo-bar — measured at 767 */
    }
}
body.profile-dashboard-active:not(.profile-editor-active) .section-nav-bar {
    top: var(--site-header-clear);
}
/* end of 42.2a */
.section-nav {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-sm);
    justify-content: center;
    margin: 0;
    padding: var(--sp-sm);
    background: var(--color-surface);
    border: 1.5px solid var(--color-gold);
    border-radius: var(--radius-md);
    width: fit-content;
    max-width: 100%;
    box-shadow: var(--shadow-sm);
}
/* S224 14/09/26, Rob by AskUserQuestion on a three-way sheet at 360: "Yes, solid white with
   the chosen one cream". The three pills were see-through, so on the profile page they took
   the page's own pale grey and read as unfilled. All three states that were transparent are
   now white; the behaviour is unchanged (hover and press still do not change the fill, only
   the lift), and the chosen pill keeps its cream from the rule below. */
.section-nav__item {
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 13px;
    color: var(--color-navy) !important;
    /* -1px each side to compensate for the border so layout doesn't shift */
    padding: 7px 17px;
    margin-bottom: 0; /* defeats Seeko button { margin-bottom: 1rem } from seeko-dynamic.css */
    border-radius: 10px;
    border: 1px solid var(--color-gold) !important;
    background: #FFFFFF !important;
    cursor: pointer;
    white-space: nowrap;
    letter-spacing: 0.02em;
    /* No native focus / tap indicators on these pills. The pill's own
       transform + gold `--active` fill are the only visual states the design
       calls for. Browser defaults (grey focus ring on click, grey outline on
       :focus-visible, mobile tap-highlight overlay) all read as "the tab went
       grey" and were reported as broken by Rob 08/07/26. Killed everywhere. */
    outline: none !important;
    -webkit-tap-highlight-color: transparent;
    /* Resting = raised. Outer drop shadow gives "ready to be clicked" feel. */
    box-shadow: var(--shadow-gold-hover);
    transform: translateY(-1px);
    transition: transform 120ms var(--ease-out),
                box-shadow 120ms var(--ease-out),
                background-color 120ms var(--ease-out),
                border-color 120ms var(--ease-out),
                color 120ms var(--ease-out);
    will-change: transform;
}
.section-nav__item:hover:not(.section-nav__item--active),
html[data-nav="kbd"] .section-nav__item:focus:not(.section-nav__item--active),
html[data-nav="kbd"] .section-nav__item:focus-visible:not(.section-nav__item--active),
html[data-nav="kbd"] .section-nav__item:focus-within:not(.section-nav__item--active) {
    background: #FFFFFF !important;
    border-color: var(--color-gold) !important;
    color: var(--color-navy) !important;
    outline: none !important;
    box-shadow: var(--shadow-gold-hover) !important;
}
.section-nav__item:active:not(.section-nav__item--active) {
    background: #FFFFFF !important;
    border-color: var(--color-gold) !important;
    color: var(--color-navy) !important;
    outline: none !important;
    transform: translateY(0);
    box-shadow: none !important;
    transition-duration: 50ms;
}
/* Active pill — gold-filled, navy text, sits flush. Focus / active pseudos
   collapsed into the same rule so a clicked-then-focused active pill can
   never revert to a grey browser-default state. */
/* S213 08/09/26, Rob's ruling, asked and answered: "Change it to the darker cream." A4 says every
   dark gold button becomes light cream with the DARKER cream on hover and select, and S207 applied
   exactly that to the sibling class .btn-menu--active (8955 in this file) - but the live tab bars
   are built on .section-nav__item, which that change never reached, so the selected tab stayed a
   solid gold pill on every dashboard page. Brought onto the same pairing as its sibling. This
   supersedes BRAND_GUIDE 9.4's gold-selected row, which is now stale for both classes. */
.section-nav__item--active,
.section-nav__item--active:hover,
.section-nav__item--active:focus,
.section-nav__item--active:focus-visible,
.section-nav__item--active:focus-within,
.section-nav__item--active:active {
    background: var(--color-cream-hover, #FFF5CC) !important;
    color: var(--color-navy) !important;
    border-color: var(--color-gold) !important;
    outline: none !important;
    transform: translateY(0);
    box-shadow: none !important;
    cursor: default;
}
/* Global suppression of Firefox's inner dotted outline on ANY button that
   picks up section-nav-style focus (dashboard pills across every workspace).
   Rob 08/07/26 — no focus rings on section-nav pills, anywhere. */
.section-nav__item::-moz-focus-inner { border: 0 !important; }
/* end of 42.2 */

/* 42.3 Sections — only the active one is visible (PHP toggles data-active) */
.workspace > .section {
    margin-bottom: var(--sp-3xl);
    scroll-margin-top: 80px;
}
.workspace > .section[data-active="false"] { display: none; }
.profile-public-wrapper > .section[data-active="false"] { display: none; }
.section__heading {
    text-align: center;
    margin-bottom: var(--sp-xl);
}
.section__title {
    font-family: var(--font-heading);
    font-size: 24px !important;
    font-weight: 700;
    color: var(--color-navy);
    margin-bottom: var(--sp-xs);
    line-height: 1.2;
}
.section__hint {
    font-size: 15px;
    color: var(--color-text-secondary);
}
/* end of 42.3 */

/* 42.4 Card — canonical white surface + 1.5px gold border + 16px radius.
   S87 cascade fix: scoped to `.workspace` because Bootstrap-bundled plugin CSS
   may also define `.card`. Same family of fix as S86-010 modal rename. */
.workspace .card {
    background: var(--color-surface);
    border: 1.5px solid var(--color-gold);
    border-radius: var(--radius-md);
    padding: var(--sp-xl);
    box-shadow: var(--shadow-sm);
}
.workspace .card + .card { margin-top: var(--sp-lg); }
.workspace .card--centered { text-align: center; }
.workspace .card--centered .card__title,
.workspace .card--centered .card__hint { text-align: center; }
.workspace .card--centered .form-actions,
.workspace .card--centered .form-actions--start { justify-content: center; }
.workspace .card--centered .toggle-row {
    grid-template-columns: 1fr;
    justify-items: center;
    align-items: center;
    gap: var(--sp-md);
    text-align: center;
}
.workspace .card--centered .toggle-row__text { text-align: center; }
.workspace .card__title {
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 18px;
    color: var(--color-navy);
    margin-bottom: var(--sp-xs);
}
.workspace .card__hint {
    font-size: 14px;
    color: var(--color-text-secondary);
    margin-bottom: var(--sp-lg);
}
/* end of 42.4 */

/* 42.5 Tier hero — Membership section's header card.
   Note: design agent's S86 fix — .tier-hero::before 4% gold gradient overlay
   removed entirely (was creating an off-white tint instead of pure white). */
.tier-hero {
    background: var(--color-surface);
    border: 1.5px solid var(--color-gold);
    border-radius: var(--radius-md);
    padding: var(--sp-2xl);
    box-shadow: var(--shadow-sm);
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--sp-lg);
    position: relative;
    overflow: hidden;
}
/* No ::before pseudo-element — pure white card matches every other section card */
.tier-hero__main {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sp-md);
    min-width: 0;
    width: 100%;
}
.tier-hero__row {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-md);
    flex-wrap: nowrap;
    min-width: 0;
}
.tier-hero__row .tier-badge { flex: 0 0 auto; }
.tier-hero__row .tier-hero__label {
    flex: 0 1 auto;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.tier-hero__label {
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    /* S245 row 48 (Rob, the 7th of October 2026: "Member since..../Price/next bill/renews should all be in gold"). Was var(--color-text-muted), the 55 percent navy.
       Gold is --color-gold, the same token as the 1.5px border of .tier-hero above (42.5) and the amount on the Invoices cards (42.24). */
    color: var(--color-gold);
}
.tier-hero__name {
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 32px;
    color: var(--color-navy);
    letter-spacing: -0.01em;
}
.tier-hero__meta {
    display: flex;
    gap: var(--sp-2xl);
    margin-top: var(--sp-sm);
    flex-wrap: wrap;
    justify-content: center;
}
.tier-hero__meta-item {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.tier-hero__meta-label {
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    /* S245 row 48: gold like .tier-hero__label above (was var(--color-text-muted)); the values underneath stay navy. */
    color: var(--color-gold);
}
.tier-hero__meta-value {
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 16px;
    color: var(--color-navy);
}
.tier-hero__interval {
    font-weight: 400;
    color: var(--color-text-secondary);
}
.tier-hero__actions {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: var(--sp-sm);
}
/* end of 42.5 */

/* 42.6 Tier status banner — inside tier-hero for past-due / cancelled / active */
.tier-status {
    margin-top: var(--sp-md);
    padding: var(--sp-md) var(--sp-lg);
    border-radius: var(--radius-md);
    border: 1.5px solid var(--color-gold);
    display: flex;
    align-items: flex-start;
    gap: var(--sp-md);
    font-size: 14px;
    line-height: 1.5;
}
/* S87 ported the design's variants as background + colour only, leaving the base rule's GOLD
   border on all three. S213 (Rob 08/09/26, on the green one): "that's a green notice panel. And
   the board is fucking gold. It should be the dark green, just like the font in the middle, the
   text." So each variant now carries its own border rather than borrowing the card system's gold.
   Warn and err are brought with it: the same fault, and a ring that disagrees with its message is
   the thing he is objecting to, not the colour green specifically. */
.tier-status--ok   { background: var(--color-success-bg); color: var(--color-success); border-color: var(--color-success); }
.tier-status--warn { background: var(--color-warning-bg); color: var(--color-warning); border-color: var(--color-warning); }
.tier-status--err  { background: var(--color-error-bg);   color: var(--color-error);   border-color: var(--color-error); }
.tier-status__icon { flex-shrink: 0; margin-top: 2px; }
/* Active state: no icon, centred title + body (Rob 09/05/26) */
.tier-status--centered { justify-content: center; text-align: center; }
.tier-status__title {
    font-weight: 700;
    font-family: var(--font-heading);
    color: inherit;
    margin-bottom: 2px;
}
/* end of 42.6 */

/* 42.7 Tier badge — small pill marking the current tier. Padding corrected INK-ROBUST-2
   25/09/2026 (coordinator, after Rob's items 6/7 verdicts): raster (a) is 412w dpr2.625, Rob's
   own phone - 0.381px there is a full DEVICE pixel at his density, not sub-pixel noise, and the
   prior 5px/3px measured +0.381px low on that raster specifically (drifted there from an
   earlier +0.063px at dpr8 as other concurrent edits shifted the page). Bracketed at raster (a)
   in 0.25px steps, sum held within 1px of the original 8px: 5px/4px (sum 9) lands dy 0, 0, 0,
   0.063px on all four canonical rasters (412w dpr2.625, 360w dpr3, 360w dpr2, 360w dpr8) -
   results/s235/ink-robust/. */
.tier-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    padding: 5px 12px 4px;
    border-radius: var(--radius-pill);
}
/* R3-06 24/09/2026, Rob (item 6): "I've never agreed to the brand including grey anywhere,
   ever." Overrides BRAND_GUIDE 11's grey (S227 item 78) at its source, rule of one: cream/
   gold-border/navy, the same recipe as the platform's other cream-and-gold pill,
   .sessions-list__current-pill (page-polish.css 42.17) - radius and padding stay the
   base .tier-badge rule above, unchanged. */
/* D-652 25/09/2026, Rob: "all tier pills cream and gold." Every variant below now carries the
   same three values as --free (Rule of one, replaced at source): the per-tier tint palette is
   retired, --dating is added (was missing outright - Rule 13, a Dating member had bare text). */
.tier-badge--free      { color: var(--color-navy); background: var(--color-cream); border: 1px solid var(--color-gold); }
.tier-badge--standard  { color: var(--color-navy); background: var(--color-cream); border: 1px solid var(--color-gold); }
.tier-badge--premium   { color: var(--color-navy); background: var(--color-cream); border: 1px solid var(--color-gold); }
.tier-badge--venue     { color: var(--color-navy); background: var(--color-cream); border: 1px solid var(--color-gold); }
.tier-badge--organiser { color: var(--color-navy); background: var(--color-cream); border: 1px solid var(--color-gold); }
.tier-badge--dating    { color: var(--color-navy); background: var(--color-cream); border: 1px solid var(--color-gold); }
/* end of 42.7 */

/* 42.8 Buttons — canonical .btn family. LB-023 = .btn--primary (cream + gold border + navy text)
   S87 cascade fix: every primitive scoped to `.workspace` so the design's
   values (specificity 0,2,0) beat Seeko parent's `.btn` (0,1,0 source-order win)
   and `input[type="text"]` (0,1,1) rules. Per design agent's README §10:
   "Brand tokens already in page-polish.css. Do not redefine in this page's CSS." */
/* S215 (GAL-25): the gallery modals are attached to document.body, not into the workspace,
   so a .workspace-scoped shape primitive never reached their buttons. The COLOURS did reach
   (42.8 .btn.btn--primary below is unscoped), which is why the S179 fix looked right in the
   source and still rendered wrong on screen. Widened rather than duplicated, per the
   no-new-CSS rule: the class was right, the scope was the mistake. */
.workspace .btn,
.gal-modal .btn,
.gal-lightbox .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-sm);
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 14px;
    line-height: 1;
    padding: 10.5px 24px;
    border-radius: 10px;
    border: 2px solid transparent;
    cursor: pointer;
    transition: all var(--duration-fast) var(--ease-out);
    white-space: nowrap;
    text-decoration: none;
    background: transparent;
    text-transform: none;
    margin: 0;
    letter-spacing: normal;
    /* R3-17/18 (24/09/2026): .gal-modal and .gal-lightbox are relocated to <body> when opened
       (GAL-25), outside .workspace, so Android's default translucent tap-highlight overlay was
       the only thing painting on press - it read as an unstyled grey/black button (Rob's items
       17 + 18) because our own :active/:disabled colours below could not out-paint it. */
    -webkit-tap-highlight-color: transparent;
}
.workspace .btn:hover { text-decoration: none; }
/* S222 (Rob, 14/09/2026, items 3/16/43/109 read together): "Saving should be shown the same
   everywhere and it should not grey out." This is the same wipe as 43.2 was, on the dashboard's
   own generic button. COMPUTED painted result before, from a compositing model checked against
   the measured pixels on the bank button to within 1 of 255: rgb(184,190,220) on rgb(245,246,250),
   1.70 to 1. It now keeps the button's own colours, as 46.Z does. */
.workspace .btn:disabled,
.workspace .btn--disabled {
    opacity: 1;
    cursor: not-allowed;
}
/* Variants below use class-chained selectors (.btn.btn--variant) so the rules
   land at specificity (0,2,0) — beats Seeko parent's bare `body button { ... }`
   element rules (0,0,1 + element) which were re-skinning <button> elements
   regardless of class. Same family of override as S64 cache war + S85 LB-055
   button-margin. */
/* UPG-1 (S238, Rob 28/09/2026 on the upgrade gate's "Upgrade now": "look at this button on hover!? No border,
   black text"). The Seeko parent's seeko-dynamic.css ".btn:hover" (0,2,0, loaded after this sheet) paints
   color #191919, background #f0f0f0 and border-color transparent on every hovered .btn, and the hover rule below
   only ever restated the background, the lift and the shadow, so every primary button outside #buddypress
   .workspace lost its gold border and turned its label black on hover (read with CDP getMatchedStylesForNode on
   the live gate). :hover now carries the rest colours at (0,3,0), OUTSIDE the hover media gate on purpose: a phone
   keeps :hover after a tap (L-340) and the S224 item 64 gate below never applies there, so Seeko's grey, black,
   borderless hover was what a tapped button showed. The gated rule below still adds the darker cream and the
   lift on a real pointer; :active and :disabled after it still win. Same values as the workspace rule
   (#buddypress .workspace .btn.btn--primary:hover, 42.8.1), so the two surfaces now hover alike. */
.btn.btn--primary,
.btn.btn--primary:hover {
    background: var(--color-cream);
    border-color: var(--color-gold);
    color: var(--color-navy);
    box-shadow: var(--shadow-gold-hover);
}
/* R3-17/18 (24/09/2026): unscoped so it also reaches .gal-lightbox/.gal-modal buttons, which sit
   outside #buddypress .workspace once open and so never matched that rule's higher-specificity
   :active treatment below (that one still wins wherever it applies - this only fills the gap).
   D-640 treats "pressed" and "in-flight" (:disabled, e.g. the Download button while its native
   save prompt is up, or Delete while its request is in flight) as the one same look. */
.btn.btn--primary:active,
.btn.btn--primary:disabled {
    background: var(--color-cream-hover);
    border-color: var(--color-gold);
    box-shadow: none;
}
.btn.btn--primary:disabled {
    opacity: 1;
    cursor: not-allowed;
}
/* S224 item 64: gated so a tap on a phone cannot leave the button painted dark cream.
   :active below still paints it on the press itself, which is the feedback Rob asked for.
   S244 row 119 (Rob, the 8th of October 2026: the canonical button's three states): this rule is :hover:not(:active). It was :hover, at the same
   specificity as .btn.btn--primary:active above and later in the file, so on a button held down BOTH matched and this one won, and the same was true of
   the workspace copy at 42.8.1 below (the one the Messages buttons use): measured live with the pointer held down on the Bin's Restore button, it kept
   translateY(-1px) and the 0 4px 12px shadow, exactly as hovered, instead of the D-640 pressed look, darker cream with no shadow. The press now belongs to
   the :active rules, which is what they were written for. */
@media (hover: hover) {
.btn.btn--primary:hover:not(:active):not(:disabled) {
    background: var(--color-cream-hover);
    transform: translateY(-1px);
    box-shadow: var(--shadow-gold-hover);
}
}
.btn.btn--ghost {
    background: transparent;
    border-color: var(--color-navy);
    color: var(--color-navy);
}
.btn.btn--ghost:hover {
    background: var(--color-navy);
    color: var(--color-gold);
}
/* S219 (Rob 10/09/26, on Decline): "Stays red, but make sure it's the light background and darker
   border and text, not like a block of red". The brand error wash at rest, a deeper wash on hover. */
.btn.btn--danger {
    background: var(--color-error-bg, rgba(196, 28, 28, 0.06));
    border-color: var(--color-error);
    color: var(--color-error);
    box-shadow: var(--shadow-gold-hover);
}
/* S244 row 112 (Rob, the 8th of October 2026: "The delete button doesn't have a pop on hover either, like the other button ... all the buttons that do
   something negative like delete or report, they don't have the full animation, they don't pop when you hover"). The site's one red button had the deeper
   wash on hover and nothing else: measured live on the Bin's Delete for good and the Attendance Cancel, hovered, transform none against the lift
   translateY(-1px) that the Restore button beside it takes. It now takes exactly the pop its sibling .btn--primary has just above: the colours stay
   ungated (they are all this rule ever did), and the lift and its shadow (the same --shadow-gold-hover the rest state carries) are gated to a real pointer
   and stand down while the button is held, as .btn--primary's do. border-color is stated here too, and the pressed rule below carries Seeko's own :not() shape:
   Seeko's seeko-dynamic.css `.btn:hover` (0,2,0, loaded after this sheet) clears the ring and its `.btn:not([disabled]):not(.disabled):active` (0,4,0) paints grey #eee
   with a #191919 label, and outside #buddypress .workspace nothing restated either. MEASURED LIVE on a copy of the Event Invites Decline button's markup placed at body
   level, where that modal puts it: hovered the ring was rgba(0,0,0,0), held down it was #eee. This is the same gap UPG-1 closed for .btn--primary. */
.btn.btn--danger:hover {
    background: rgba(196, 28, 28, 0.12);
    color: var(--color-error);
    border-color: var(--color-error);
}
@media (hover: hover) {
.btn.btn--danger:hover:not(:active):not(:disabled) {
    transform: translateY(-1px);
    box-shadow: var(--shadow-gold-hover);
}
}
/* R3-18 (24/09/2026): same gap as .btn--primary above - the Delete button's own :disabled window
   (set by profile-system.php while its delete request is in flight) had no unscoped danger
   colour to fall back on outside #buddypress .workspace, so it painted the browser's native
   grey/black disabled look instead of the brand red. Rob, same item, next pass: "There's no
   border." Background/shadow were covered here but border-color never was, so the Seeko parent
   theme's own equal-specificity seeko-dynamic.css .btn:disabled { border-color: transparent }
   kept winning on source order. border-color here is specificity (0,3,0), which beats it
   outright, no !important needed. */
.btn.btn--danger:not([disabled]):not(.disabled):active,
.btn.btn--danger:disabled {
    background: rgba(196, 28, 28, 0.12);
    border-color: var(--color-error);
    color: var(--color-error);
    box-shadow: none;
}
.btn.btn--danger:disabled {
    opacity: 1;
    cursor: not-allowed;
}
.btn.btn--subtle {
    background: transparent;
    border: 0;
    color: var(--color-navy);
    padding: 6px 8px;
    font-weight: 600;
    font-size: 13px;
    border-radius: 10px;
}
.btn.btn--subtle:hover {
    background: var(--color-surface-raised);
    text-decoration: none;
}
.workspace .btn--icon {
    padding: 6px;
    display: inline-grid;
    place-items: center;
    line-height: 0;
}
.workspace .btn--icon svg { display: block; }
.workspace .btn--sm,
.gal-modal .btn--sm,
.gal-lightbox .btn--sm { padding: 8px 16px; font-size: 13px; }
.workspace .btn--block { width: 100%; }
.workspace .btn-row    { display: flex; gap: var(--sp-md); flex-wrap: wrap; }
/* end of 42.8 */

/* 42.8.1 BP submit cascade fix — §18.1.0.1 sets background:white !important and §18.1.0.2
   sets hover:navy !important on ALL #buddypress button[type="submit"], which includes our
   workspace .btn elements (they are submit buttons inside #buddypress). Override using
   #buddypress .workspace scope (specificity 1,3,0) which beats §18's (1,0,1). */
#buddypress .workspace .btn.btn--primary {
    background: var(--color-cream) !important;
    border-color: var(--color-gold) !important;
    color: var(--color-navy) !important;
    box-shadow: var(--shadow-gold-hover) !important;
}
/* Shape/typography apply to PLAIN btn--primary only. A btn--primary that also
   carries a shape variant (.att-cancel-btn — e.g. the Event Invites Accept
   button) must keep that variant's dimensions, exactly as the design intends.
   This mirrors the colours-only philosophy already used for .btn--danger below. */
#buddypress .workspace .btn.btn--primary:not(.att-cancel-btn) {
    border-radius: 10px !important;
    font-size: 14px !important;
    text-transform: none !important;
    letter-spacing: normal !important;
    /* S235 item 23 (Rob, 24/09/2026): "the label is not centred, this one is too low." First
       pass bracketed padding-top/bottom together (10.5/10.5 -> 10.25/10.75) and only reached
       0.44px high - still outside Rob's "properly centred". Chromium snaps this line box's
       baseline to the nearest whole CSS px, so a coarse two-point bracket lands on a plateau's
       edge rather than its middle. Re-swept properly: padding-top held at 10.25px, padding-
       bottom scanned 9.5px to 12px in 0.125px steps, measured by ink at dpr 8 each time
       (Browse events, /attendance/, jack). Two equal-width 0.25px plateaus measured 0.06px
       (the closest to zero either reached): bottom 9.5-9.75px, and bottom 10.125-10.375px.
       Took the middle of the second (10.25px, symmetric with the top value already set,
       sum 20.5px vs the original 21px - closer to the original than the other plateau's
       19.875px). Confirmed within 0.5px on the dashboard's own "Browse events"
       (att-empty-state__cta reused, profile-system.php, 0.06px), the Favourites empty state
       (uksocials-member-favourites.php, 0.06px) and the dashboard Randomise button
       (dashboard-randomise-btn, 0.50px, its own independent plateau, unchanged from the
       first pass - not this rule's fault, see the report).
       BTN-1 (Rob, 28/09/2026, corrected 28/09/2026 after the coordinator's ruling - Context
       Guard/COMMENTS.md line 122, 25/09/2026: "the highest point of the text is the capital
       letter... vertical centre of the labels is measured against the tallest letter, which is
       capitalised" - a descender is real ink that is SUPPOSED to hang below centre, it is not
       part of the measure). Measuring the CAPITAL LETTER's own ink only (a DOM Range over the
       "S" of "Save changes", rasterised at device scale 4, ink rows at any colour-match - see
       BTN-1/RECORD.md): this button's capital sits 0.763 to 0.776px low at 1920/1280/360 and
       0.241 to 0.25px HIGH at 1024/768/600 - a real, if small, shared fault (matches Cancel's
       own capital within 0.2-0.25px, both governed by the same intrinsic font-metric bias).
       Bracket-swept live at both snap buckets: a 0.5px top-to-bottom shift (half of the 1.5px
       this file previously carried, which was chosen against the FULL ink box including the
       descender in "changes" and has been corrected) lands both buckets at -0.23 to -0.25px,
       comfortably centred; sum unchanged at 20.5px so the button's outer height does not move. */
    padding: 9.75px 24px 10.75px !important;
    line-height: 1 !important;
}
/* S215 (DASH-19): there was a rule for :hover and none at all for :active or :focus, so a
   held or focused primary button fell through to whatever the parent theme paints and went
   dark on click. Rob's rule was light cream at rest and darker cream on hover AND on select,
   so the pressed and focused states joined the hover rule. The focus ring at section 50 is
   an outline, not a box-shadow, so it is untouched by this.
   R3-08 (24/09/2026, D-640): reversed the shadow half of that - the rest state now carries
   the gold lift always (not just on hover), and :active drops it instead of gaining it, so a
   press reads as "pushed in" rather than "lifted further". Kept split from :focus below,
   which still gets the lift as its keyboard-visible affordance.
   S244 row 119 (Rob, the 8th of October 2026: "the canonical button styles ... for both hover and click, and then when it is saving too"): :disabled joins this rule. D-640 and the
   unscoped rules above (R3-17/18) treat pressed and in-flight as the one same look, but this workspace copy only ever named :active, so inside #buddypress .workspace a button
   in flight fell back to the rule above (light cream and the 0 4px 12px shadow, identical to rest, cursor not-allowed): measured live on the Compose tab's Send with its
   disabled attribute set, which is how messages-app.js sends. It now takes the pressed look: the darker cream, the ring, the label, no shadow. */
#buddypress .workspace .btn.btn--primary:active,
#buddypress .workspace .btn.btn--primary:disabled {
    background: var(--color-cream-hover) !important;
    border-color: var(--color-gold) !important;
    color: var(--color-navy) !important;
    box-shadow: none !important;
}
html[data-nav="kbd"] #buddypress .workspace .btn.btn--primary:focus {
    background: var(--color-cream-hover) !important;
    border-color: var(--color-gold) !important;
    color: var(--color-navy) !important;
    box-shadow: var(--shadow-gold-hover) !important;
}
@media (hover: hover) {
#buddypress .workspace .btn.btn--primary:hover:not(:active):not(:disabled) {
    background: var(--color-cream-hover) !important;
    border-color: var(--color-gold) !important;
    color: var(--color-navy) !important;
    box-shadow: var(--shadow-gold-hover) !important;
    transform: translateY(-1px);
}
}
#buddypress .workspace .btn.btn--ghost {
    background: transparent !important;
    border-color: var(--color-navy) !important;
    color: var(--color-navy) !important;
    border-radius: 10px !important;
    font-size: 14px !important;
    text-transform: none !important;
    letter-spacing: normal !important;
    padding: 10.5px 24px !important;
    line-height: 1 !important;
}
#buddypress .workspace .btn.btn--ghost:hover {
    background: var(--color-navy) !important;
    color: var(--color-gold) !important;
    border-color: var(--color-navy) !important;
}
/* When BOTH .btn--ghost and .btn--sm are present (e.g. account "Pause account"
   button next to "Delete account…"), the small-variant sizing wins over
   ghost's default padding/font. Without this, ghost's 11/24/10 padding +
   font-size 14 leaked through and made the pill 6px taller than the sibling
   danger .btn--sm button beside it. Specificity 1,4,0 beats ghost's 1,3,0.
   (Rob 09/07/26.) */
#buddypress .workspace .btn.btn--ghost.btn--sm {
    padding: 8px 16px !important;
    font-size: 13px !important;
}
/* R3-13 (24/09/2026): .btn--primary needs the same sm-size correction as ghost above,
   now that Pause account uses btn--primary at rest (D-640) - without it the shape
   rule's own 10.5px/24px padding beat the plain .btn--sm rule (no !important) and
   Pause rendered larger than Delete beside it. */
#buddypress .workspace .btn.btn--primary.btn--sm {
    padding: 8px 16px !important;
    font-size: 13px !important;
}
/* S245 row 55 (Rob, the 7th of October 2026, on the questionnaire's Back, Next and Saving... buttons: "the labels are low again. I don't understand why that keeps happening"; LABELS-1).
   WHY IT KEEPS HAPPENING, read off the live cascade: four rules reach a small primary button: 42.8 `.workspace .btn` (padding 10.5px 24px), 42.8 `.workspace .btn--sm` (8px 16px), 42.8.1
   `.btn--primary:not(.att-cancel-btn)` (9.75px 24px 10.75px !important, the 0.5px lift that centred the regular size, S235 item 23 and BTN-1) and the rule just above, added by R3-13 to stop
   Pause account rendering large, which restated padding as the symmetrical 8px 16px !important and so left every small primary button with the label low. THE FAULT IS A PARITY ONE (da.md 21b,
   the even-box rule): the capital letters paint 10 rows high and the button's inner area (35px box, 2px ring each side) is 31 rows, an odd number, so the label can only sit one row higher or one
   row lower than the middle and never on it. MEASURED on example_aaron_fitzgerald's step 6 against the PAINTED ring (the eye's own reference): the capital letter's ink sat 0.95px low in the
   comparison engine's capture (scale 8), 0.50px low at 100 per cent and 0.80px low at 125 per cent (Rob's own screenshot of this button: 11 rows above the word, 10 below). Shifting the label
   up one row only turns "0.5 low" into "0.5 high" at 100 per cent (6.5px top measured -0.50). The fix is the recipe da.md gives: ONE pixel on the trailing edge. 1px more under the label makes the
   box 36px and the inner area 32 rows, even, with the label where it already was: measured against the painted ring 0.44 (engine capture), 0.00 (100 per cent), 0.40 (125 per cent) at 1280, and
   0.44, 0.00, 0.80 at 360.
   WHY THIS IS A SCOPED RULE AND NOT A CHANGE TO THE SHARED ONE ABOVE: the shared rule also sets Pause account, which sits beside Delete account (a danger small button, 33px) and must stay the
   same height (R3-13's own reason). MEASURED with the extra pixel on the shared rule: Pause 34px against Delete 33px. So the wizard's own two buttons take the pixel here, and the other
   small primary buttons are unchanged until Rob rules on the whole family (Pause and Delete, Issue refund and the rest carry the same half-pixel fault). */
#buddypress .workspace .pf-nav .btn.btn--primary.btn--sm {
    padding: 8px 16px 9px !important;
}
/* Only colours — typography/dimensions come from .btn + variant modifiers
   (e.g. .att-cancel-btn). Stale font-size/border-radius/text-transform/letter-spacing
   forced here forced cancel-btn into the wrong shape and required band-aid scope-bumps
   to undo. Stripping them lets each .btn--danger variant own its own dimensions cleanly. */
#buddypress .workspace .btn.btn--danger {
    background: var(--color-error-bg, rgba(196, 28, 28, 0.06)) !important;
    border-color: var(--color-error) !important;
    color: var(--color-error) !important;
    box-shadow: var(--shadow-gold-hover) !important;
}
#buddypress .workspace .btn.btn--danger:hover {
    background: rgba(196, 28, 28, 0.12) !important;
    color: var(--color-error) !important;
    border-color: var(--color-error) !important;
}
/* S244 row 112: the pop, the same pair .btn--primary has above (42.8.1) and gated the same way; see 42.8 for the measurements. */
@media (hover: hover) {
#buddypress .workspace .btn.btn--danger:hover:not(:active):not(:disabled) {
    box-shadow: var(--shadow-gold-hover) !important;
    transform: translateY(-1px);
}
}
/* Pressed and in flight are the one look (D-640), as for .btn--primary above: the deeper wash, the ring, the label, no shadow. */
#buddypress .workspace .btn.btn--danger:active,
#buddypress .workspace .btn.btn--danger:disabled {
    background: rgba(196, 28, 28, 0.12) !important;
    border-color: var(--color-error) !important;
    color: var(--color-error) !important;
    box-shadow: none !important;
}
#buddypress .workspace .btn.btn--subtle {
    background: transparent !important;
    border: 0 !important;
    text-transform: none !important;
    font-size: 13px !important;
    letter-spacing: normal !important;
}
#buddypress .workspace .btn.btn--subtle:hover {
    background: var(--color-surface-raised) !important;
    color: var(--color-navy) !important;
}
/* 42.8.2 S227 item 72, Rob (stands as triaged): the Cancel under Save changes "shows as
   plain unstyled text, unlike the bordered Save changes button right above it". This is the
   account page's three form action rows only (Account details, Password, Billing); the
   shared .btn--subtle text link, including the questionnaire Skip, is untouched. Colours are
   Rob's own words on image 68, the same kind of secondary button on the same page: "Leave
   the background white but give it a gold border." Geometry is .btn--primary's, measured
   live: 10px corners, 14px/700, 10.5px 24px, the platform two-part navy shadow (D-508).
   !important only where 42.8.1 above uses it.
   S245 row 48 (Rob, the 7th of October 2026: Cancel membership "should be a button"; D-512, the site's own button, no fourth family). The Cancel
   membership button on the Membership card (functions.php 7.3.2, .tier-hero__actions) is a bare .btn--subtle text link next to the bordered Manage
   subscription, which is exactly the fault this block fixed for the Cancel under Save changes. It is the same kind of secondary button on the same page, so
   it joins this block (widened, not duplicated, as 42.8 did for the gallery modals): white ground, 2px gold border, navy label, 10px corners, 14px/700,
   the platform shadow, cream on hover. Only the pop below is added, and only for this scope: the Account details Cancel is left exactly as signed off. */
#buddypress .workspace .form-actions .btn.btn--subtle,
#buddypress .workspace .tier-hero__actions .btn.btn--subtle {
    background: #FFFFFF !important;
    border: 2px solid var(--color-gold) !important;
    color: var(--color-navy);
    border-radius: 10px;
    /* BTN-1 (Rob, 28/09/2026, capital-letter measure - see the account-save rule above and
       BTN-1/RECORD.md): the "C" of "Cancel" sits 0.526 to 0.53px low at 1920/1280/360 and
       0.471 to 0.479px HIGH at 1024/768/600. Bracket-swept live: a 0.5px top-to-bottom shift
       lands both buckets at -0.47 to -0.48px; sum unchanged at 21px. */
    padding: 10px 24px 11px;
    font-size: 14px !important;
    font-weight: 700;
    box-shadow: var(--shadow-gold-hover);
}
#buddypress .workspace .form-actions .btn.btn--subtle:hover,
#buddypress .workspace .tier-hero__actions .btn.btn--subtle:hover {
    background: var(--color-cream) !important;
    color: var(--color-navy) !important;
}
#buddypress .workspace .form-actions .btn.btn--subtle:active,
#buddypress .workspace .tier-hero__actions .btn.btn--subtle:active {
    box-shadow: none;
}
/* S245 row 48, the pop. Manage subscription beside it lifts 1px on a real pointer (measured live 9th of October 2026: transform matrix(1, 0, 0, 1, 0, -1), the shadow
   unchanged, see .btn.btn--primary:hover:not(:active) in 42.8), and Rob's rule of the 8th of October 2026 (row 112) is that a button that cancels or deletes must pop
   like the rest. Same lift, same pointer gate, standing down while the button is held, exactly as .btn--primary and .btn--danger do. */
@media (hover: hover) {
#buddypress .workspace .tier-hero__actions .btn.btn--subtle:hover:not(:active):not(:disabled) {
    transform: translateY(-1px);
}
}
/* end of 42.8.2 */
/* end of 42.8.1 */

/* 42.9 Forms — S87 cascade fix: scoped to `.workspace` so the gold-bordered
   centre-text input style (specificity 0,2,0) beats Seeko parent + theme-static
   `input[type="text"]` rules (0,1,1). */
.workspace .form-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--sp-lg);
}
.workspace .form-grid--single { grid-template-columns: 1fr; }
.workspace .form-row {
    display: flex;
    flex-direction: column;
    gap: 6px;
    align-items: center;
    text-align: center;
}
.workspace .form-row--full { grid-column: 1 / -1; }
.workspace .form-label {
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 13px;
    color: var(--color-navy);
    letter-spacing: 0.01em;
    text-transform: none;
}
.workspace .form-hint {
    font-size: 12px;
    color: var(--color-text-secondary);
}
.workspace .form-input,
.workspace .form-select,
.workspace .form-textarea {
    width: 100%;
    /* S227 item 77, Rob: the hint "is also too far away. You need to budge it up closer."
       theme-static.min.css sets input{margin-bottom:1rem}; the .uks-page-shell twin of this
       rule already resets it and this one did not, so Username / Email / Postcode sat their
       hint 22px below the field while Sex and Date of birth, whose control is a div, sat at
       6px. One gap for the whole card now: .form-row's own 6px. */
    margin-bottom: 0;
    padding: 11px 14px;
    font: 400 14px var(--font-body);
    color: var(--color-navy);
    background: var(--color-surface);
    border: 2px solid var(--color-gold);
    border-radius: var(--radius-md);
    outline: none;
    text-align: center;
    transition: box-shadow var(--duration-fast) var(--ease-out);
}
.workspace .form-input::placeholder,
.workspace .form-textarea::placeholder {
    color: var(--color-navy);
    opacity: 1;
    text-align: center;
}
.workspace .form-input:hover,
.workspace .form-select:hover { border-color: var(--color-gold) !important; }
html[data-nav="kbd"] .workspace .form-input:focus,
html[data-nav="kbd"] .workspace .form-select:focus { outline: none !important; border-color: var(--color-gold) !important; box-shadow: 0 0 0 2px rgba(204, 153, 0, 0.25) !important; }
.workspace .form-input:disabled {
    background: #FFFFFF;  /* S227 item 77, Rob: "make the background white". BRAND_GUIDE 13 / LB-024:
                            a form input is white, never grey. Measured before rgb(243,242,239). */
    color: var(--color-text-muted);
    cursor: not-allowed;
}
.workspace .form-actions {
    display: flex;
    justify-content: flex-end;
    gap: var(--sp-md);
    margin-top: var(--sp-lg);
}
.workspace .form-actions--start { justify-content: flex-start; }
/* end of 42.9 */

/* 42.10 Modal — used for cancel + delete confirm dialogs.
   Specificity scope-bump defeats Bootstrap's `.modal { display:none }` (0,1,0):
   .modal-backdrop > .modal has specificity 0,2,0 — beats Bootstrap cleanly. */
.modal-backdrop > .modal { display: block; }
.modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(3, 27, 131, 0.45);
    display: grid;
    place-items: center;
    z-index: 100;
    padding: var(--sp-xl);
    animation: modal-fade-in var(--duration-fast) var(--ease-out);
}
.modal-backdrop[hidden] { display: none; }
@keyframes modal-fade-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}
/* S100 26/05/26: scoped to :not(#inviteModal) because the BP invite modal uses
   the .modal class but needs to be a full-viewport overlay (its own styling
   lives in invite-system.php). This rule was painting the invite modal as a
   480px-wide side panel. */
.modal:not(#inviteModal) {
    background: var(--color-surface);
    border: 2px solid var(--color-gold);
    border-radius: var(--radius-md);
    padding: var(--sp-2xl);
    max-width: 480px;
    width: 100%;
    box-shadow: 0 20px 60px rgba(3, 27, 131, 0.30);
}
.modal__title {
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 22px;
    color: var(--color-navy);
    margin: 0 0 var(--sp-md);
    letter-spacing: -0.01em;
}
.modal__body {
    font-size: 15px;
    color: var(--color-text);
    margin: 0 0 var(--sp-md);
    line-height: 1.55;
    text-wrap: pretty;
}
.modal__body--muted {
    color: var(--color-text-secondary);
    font-size: 14px;
}
.modal__check {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: var(--sp-lg) 0 var(--sp-md);
    font-size: 14px;
    color: var(--color-text-secondary);
    cursor: pointer;
}
.modal__actions {
    display: flex;
    justify-content: flex-end;
    gap: var(--sp-sm);
    margin-top: var(--sp-lg);
}
/* end of 42.10 */

/* 42.11 Payment methods — saved card rows */
.method-list {
    display: flex;
    flex-direction: column;
    gap: var(--sp-md);
}
.method {
    display: grid;
    grid-template-columns: auto 1fr auto;
    gap: var(--sp-lg);
    align-items: center;
    padding: var(--sp-lg);
    background: var(--color-surface-raised);
    border: 1.5px solid var(--color-gold);
    border-radius: var(--radius-md);
}
.method--default {
    background: var(--color-cream);
    border-color: var(--color-gold);
}
.method__brand {
    width: 56px;
    height: 36px;
    border-radius: 8px;
    background: var(--color-navy);
    color: var(--color-gold);
    display: grid;
    place-items: center;
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 11px;
    letter-spacing: 0.04em;
}
.method__brand--mc     { background: linear-gradient(135deg, #EB001B, #F79E1B); color: #fff; }
.method__brand--amex   { background: #006FCF; color: #fff; }
.method__brand--paypal { background: #003087; color: #FFC43A; }
.method__num {
    font-family: var(--font-heading);
    font-weight: 700;
    color: var(--color-text);
}
.method__exp {
    font-size: 13px;
    color: var(--color-text-secondary);
    margin-top: 2px;
}
.method__actions {
    display: flex;
    gap: var(--sp-xs);
    align-items: center;
}
.method__default-pill {
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    background: var(--color-gold);
    color: var(--color-navy);
    padding: 3px 9px 4px;
    border: 1px solid var(--color-navy);
    border-radius: var(--radius-pill);
}
.add-method {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-sm);
    padding: var(--sp-lg);
    border: 2px dashed var(--color-border-strong);
    border-radius: var(--radius-md);
    color: var(--color-navy);
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 14px;
    background: transparent;
    width: 100%;
    cursor: pointer;
    transition: all var(--duration-fast) var(--ease-out);
}
.add-method--spaced { margin-top: var(--sp-md); }
.add-method:hover {
    border-color: var(--color-gold);
    background: var(--color-cream);
}
/* 42.11.1 Stripe card-storage note (D-307 pt 2, Rob's signed-off copy). Reuses the
   canonical .form-hint face; this rule only places it under the card list. */
.workspace .method-note {
    margin: var(--sp-md) 0 0;
    text-align: center;
    line-height: 1.6;
}
/* end of 42.11 */

/* 42.12 Invoice table — desktop layout */
.invoice-table { width: 100%; border-collapse: collapse; }
.invoice-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    margin: 0 calc(-1 * var(--sp-lg));
    scrollbar-width: none;
    cursor: grab;
    user-select: none;
}
.invoice-scroll::-webkit-scrollbar { display: none; }
.invoice-scroll.is-grabbing { cursor: grabbing; }
.invoice-scroll__hint {
    display: none;
    margin: var(--sp-sm) var(--sp-lg) 0;
    font-size: 12px;
    color: var(--color-text-secondary);
    text-align: right;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}
.invoice-scroll.has-overflow + .invoice-scroll__hint { display: block; }
.invoice-scroll .invoice-table { min-width: 560px; }
.invoice-table th {
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-navy);
    text-align: center;
    padding: var(--sp-md);
    border-top: 0;   /* D-658 (Rob 25/09): the parent theme's 1px #eee line above the header row */
}
.invoice-table th:last-child,
.invoice-table td:last-child {
    width: 1%;
    white-space: nowrap;
}
.invoice-table td {
    padding: var(--sp-md);
    font-size: 14px;
    font-weight: 600;
    /* S245 rows 51 and 93 (Rob, the 7th of October 2026: "blue or grey lines and black text"). Was var(--color-text), the near-black #1A1A2E. The S207 A6 grey sweeper
       (functions.php, "S207 A6 GREY-TEXT PASS") turns it navy at runtime, but it runs once per full page load, so a member who reaches Account through the sidenav's AJAX
       navigation never got that pass and saw black cells (measured live 9th of October 2026: rgb(26, 26, 46), no inline style). Navy is the th's own colour above. */
    color: var(--color-navy);
    text-align: center;
    /* S245 rows 51 and 93: the lines between the rows were the parent theme's `table td { border-top: 1px solid #eee }` (theme-static.min.css), grey, the same line D-658
       took off the th above. Declared here so this rule owns it: 1px at full-strength gold, as Rob ruled for the row lines of .event-row at S227 item 135 ("It WAS gold,
       at 18% over white, which reads grey. Full strength, the same var(--color-gold) as the card's own 1.5px edge"). */
    border-top: 1px solid var(--color-gold);
}
.invoice-table tr:last-child td { border-bottom: 0; }
/* D-658 (Rob 25/09): the desktop table's two downloads are D-640 buttons, stacked in their cell so the
   row keeps to the card's width (side by side they overflowed the 1280 card). */
/* S245 rows 51 and 93 (Rob: "the button is pressed up against one of the spacer lines. It should be a gap" and "the button sitting too high"): this rule took the cell's top
   padding to 0, so the buttons touched the line above them and sat 12px from the one below. The padding-top: 0 is gone; the cell keeps the 12px every other .invoice-table td
   has (--sp-md), so the buttons sit in the middle of their band, 12px from the line above and 12px from the line below. */
.invoice-table td.invoice-actions { white-space: normal; }
.invoice-table .invoice-download { display: inline-block; width: max-content; margin: 0 6px; }
.invoice-status {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    padding: 5.3px 12px 2.82px;   /* R3-21b v6: the glyph row snaps to whole pixels inside the pill, so the pill's own height is trimmed until its midline meets the painted ink (8x raster, dy 0) */
    border-radius: var(--radius-pill);
    white-space: nowrap;
    flex-shrink: 0;
}
.invoice-status--paid    { color: var(--color-success); background: var(--color-success-bg); border: 1.5px solid var(--color-success); }   /* R3-21b v2 (Rob 25/09): the standard green pill, with its border */
.invoice-status--pending { color: var(--color-warning); background: var(--color-warning-bg); }
.invoice-status--failed  { color: var(--color-error);   background: var(--color-error-bg); }
.invoice-empty {
    text-align: center;
    /* S227 item 65, Rob bracketed the gap above this message and the gap below it. The
       .card already insets 24px on every side; this added 32px more, so the message sat
       57px down and 44px above "Add a card". With no padding of its own the empty state
       takes the same 25px / 12px rhythm the populated card already has. */
    padding: 0;
    color: var(--color-text-secondary);
    font-size: 14px;
}
/* Invoice mobile stack — hidden by default; shown ≤599px */
.invoice-stack { display: none; }
/* end of 42.12 */

/* 42.12a The Affiliate People table. S245 row 94 (Rob, the 7th of October 2026, on the table of referred people with its seeded rows: "it looks terrible obviously, but I'm
   happy to keep that as it is. It just needs a styling pass."; the four columns, the names as links and the paging stay as Astra item 39 built them). MEASURED live on a
   member's People tab with the ten seeded rows placed in it, 1280 and 360: the parent theme's `table th` and `table td` rules (theme-static.min.css) draw a 1px #eee hairline
   above the header and above every cell (grey, which is no site colour); the cells and headings are left aligned in columns of unequal width; the names take the theme's
   gold link colour (gold type on white); and the state pills are a navy, gold, green or red tint with no border, nothing like the site's status pills. Every value below is copied from
   a surface Rob has signed off, nothing is new:
   - the table is the invoice table's (42.12 above): headings 11px, 0.08em, centred, 12px of padding, no top hairline; cells 14px, 600, centred, 12px of padding (the cells
     keep this page's navy, which is what Rob asked for on the invoice table, and its gold rules: the 2px under the headings and the 1px between rows);
   - the names are this page's own link, the one in the rules list (3.4.8 in the PHP): navy with a gold underline 2px under the words;
   - the state pills are the Attendance status pill (.att-chip, above): 11px Montserrat 700, 0.06em, uppercase, 5px 12px, radius 10px, a border, the same two colours and the
     same inline-flex centring. First month paid and Signed up take Reserved's cream, navy and gold (.att-chip--reserved), Paid to you takes Ticket's green
     (.att-chip--ticket), Refunded takes the red trio of .tier-status--err (--color-error on --color-error-bg, with the border). The height is whole pixels so the label cannot
     drift off the pill's centre wherever the pill falls on the screen, as the Messages date pill's is (row 108): a 1px border (the 1.5px of .att-chip paints as 1px at
     100%) and a 16px line, which the 1.6 line height inherited here made 17.6px, so the pill is 28px in all and the line's half-leading is a whole pixel. MEASURED from the
     painted pixels on twelve pills at twelve different page offsets: the label's capital band sits 0.00px from the pill's centre at device scale 1, 2 and 4 and 0.06px to
     0.13px at 8, in every one of them (before: a 29.6px pill whose label read 0.4px to 0.9px HIGH, a different amount in every row);
   - below 601px the table already stacks to one block per person (the page's own inline style); the stack keeps its labels left and values right, takes the same links,
     pills and hairline fix, and its values read 600 like the desktop cells.
   The page's own inline style (mu-plugins/uksocials-affiliate-tab.php 3.4.8) sets .aff-workspace .aff-table th, td, .aff-state, .aff-state--paid-month, --paid-you,
   --refunded and .aff-state-wrap at specificity (0,2,1) or (0,2,0) and comes later in the page than this file, so these selectors carry .workspace.aff-workspace (the same
   element, two classes) to outrank it. */
.workspace.aff-workspace .aff-table th,
.workspace.aff-workspace .aff-table td { border-top: 0; }
.workspace.aff-workspace .aff-table td { font-weight: 600; }
.workspace.aff-workspace .aff-table td a {
  color: var(--color-navy);
  text-decoration: underline;
  text-decoration-color: var(--color-gold);
  text-underline-offset: 2px;
}
@media (min-width: 601px) {
  .workspace.aff-workspace .aff-table th,
  .workspace.aff-workspace .aff-table td { text-align: center; padding: var(--sp-md); }
  .workspace.aff-workspace .aff-table th { font-size: 11px; letter-spacing: 0.08em; }
  .workspace.aff-workspace .aff-state-wrap { align-items: center; }
}
.workspace.aff-workspace .aff-state,
.workspace.aff-workspace .aff-state--paid-month {
  display: inline-flex;
  align-items: center;
  line-height: 16px;
  padding: 5px 12px;
  border: 1px solid var(--color-gold);
  border-radius: 10px;
  background: var(--color-cream);
  color: var(--color-navy);
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
}
.workspace.aff-workspace .aff-state--paid-you { background: var(--color-success-bg); color: var(--color-success); border-color: var(--color-success); }
.workspace.aff-workspace .aff-state--refunded { background: var(--color-error-bg); color: var(--color-error); border-color: var(--color-error); }
/* in the stacked list the Where it is label sits on the pill's line: the PHP's own 2px of top padding on the label left its capital band 2.9px above the 28px pill's centre
   (measured on the live page with the pill above); 5px puts the two within 0.1px, which is the step the Name, Joined and Tier rows already have between their label and their
   value (+0.1px). */
@media (max-width: 600px) {
  .workspace.aff-workspace .aff-table td[data-label="Where it is"]::before { padding-top: 5px; }
}

/* 42.13 Toggle row + toggle (used in Security 2FA section) */
.toggle-row {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: var(--sp-lg);
    align-items: center;
    padding: var(--sp-md) 0;
}
.toggle-row + .toggle-row { border-top: 1px solid var(--color-border); }
.toggle-row__text {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.toggle-row__title {
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 14px;
    color: var(--color-navy);
}
.toggle-row__hint {
    font-size: 13px;
    color: var(--color-text-secondary);
    text-wrap: pretty;
}
.toggle {
    width: 44px;
    height: 26px;
    background: var(--color-surface-sunken);
    border: 1.5px solid var(--color-border-strong);
    border-radius: var(--radius-pill);
    position: relative;
    cursor: pointer;
    transition: all var(--duration-fast) var(--ease-out);
    flex-shrink: 0;
}
.toggle::after {
    content: "";
    position: absolute;
    top: 2px;
    left: 2px;
    width: 19px;
    height: 19px;
    background: #FFFFFF;
    border-radius: 50%;
    box-shadow: var(--shadow-sm);
    transition: transform var(--duration-fast) var(--ease-out);
}
.toggle--on {
    background: var(--color-navy);
    border-color: var(--color-navy);
}
.toggle--on::after {
    transform: translateX(18px);
    background: var(--color-gold);
}
/* end of 42.13 */

/* 42.14 Danger zone — Pause + Delete card in Close account section.
   Scoped to .workspace so specificity (0,2,0) beats .workspace .card (0,2,0)
   by source order — .workspace .danger-zone is declared after .workspace .card. */
.workspace .danger-zone {
    border: 2px solid var(--color-error);
    background: var(--color-error-bg);
}
.workspace .danger-zone .card__title { color: var(--color-error); }
.danger-row {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: var(--sp-lg);
    align-items: center;
    padding: 18px 0;
}
.danger-row + .danger-row {
    border-top: 1px solid rgba(196, 28, 28, 0.15);
    margin-top: 4px;
}
/* Force Pause + Delete pills to identical width. Without this they size to
   their own text width (Pause: 136px, Delete: 150px), which reads as two
   inconsistent buttons stacked on the same edge. min-width covers the
   widest label with a small buffer so they always match, whatever the copy.
   (Rob 09/07/26.) */
.workspace .danger-zone .danger-row .btn { min-width: 160px !important; }
.workspace .danger-zone .btn.btn--ghost {
    background: var(--color-cream) !important;
    border-color: var(--color-gold) !important;
    color: var(--color-navy) !important;
}
.workspace .danger-zone .btn.btn--ghost:hover {
    background: var(--color-cream-hover) !important;
    border-color: var(--color-gold) !important;
    color: var(--color-navy) !important;
}
.workspace .danger-zone .btn.btn--danger {
    margin-top: 2px;
}
.danger-row__title {
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 14px;
    color: var(--color-navy);
}
.danger-row__hint {
    font-size: 13px;
    color: var(--color-text-secondary);
    margin-top: 2px;
}
/* end of 42.14 */

/* 42.15 Responsive — verbatim port of design styles.css lines 1458–1766.
   Both the @media block (all browsers) and @container vp blocks (scoped to .app) are included.
   Container queries require .app to have container-type: inline-size (§42.0). */

@media (max-width: 1023px) {
  .app {
    grid-template-columns: 1fr;
    padding: 0 var(--sp-md) var(--sp-3xl);
  }
  .sidenav { position: relative; height: auto; flex-direction: row; align-items: center; overflow-x: auto; padding: var(--sp-md); gap: var(--sp-sm); }
  .sidenav__brand, .sidenav__label, .sidenav__footer { display: none; }
  .sidenav__group { flex-direction: row; flex-wrap: nowrap; padding: 0; align-items: center; }
  .sidenav__item { white-space: nowrap; align-items: center; width: auto; }
  .sidenav__divider { width: 2px; height: 36px; margin: 0 var(--sp-md); background: var(--color-gold); border-radius: 1px; flex: 0 0 auto; opacity: 0.7; }
  .sidenav__scroll-cue {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    margin: 1px 0 calc(-1 * var(--sp-xs) - 5px); transform: translateY(-5px);
    font: 500 11px/1 var(--font-body);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-text-muted);
    user-select: none;
    pointer-events: none;
  }
  .sidenav__scroll-cue span:first-child,
  .sidenav__scroll-cue span:last-child {
    font-size: 14px;
    line-height: 1;
    color: var(--color-gold);
  }
  .workspace { padding: var(--sp-sm); }
  .section-nav-bar { margin: 0 calc(-1 * var(--sp-sm)) var(--sp-xl); padding: var(--sp-md) var(--sp-sm) var(--sp-lg); }
  .workspace__title { font-size: 28px; }
  .form-grid { grid-template-columns: 1fr; }
  .tier-hero {
    grid-template-columns: 1fr;
    text-align: center;
    gap: var(--sp-lg);
  }
  .tier-hero__main { align-items: center; gap: var(--sp-lg); }
  .tier-hero__row {
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--sp-sm);
  }
  .tier-hero__row .tier-hero__label {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    font-size: 12px;
    text-align: center;
  }
  .tier-hero__meta { justify-content: center; }
  .tier-hero__actions {
    flex-direction: row;
    justify-content: center;
    align-items: center;
  }
}

@container vp (max-width: 1023px) {
  .app {
    grid-template-columns: 1fr;
    padding: 0 var(--sp-md) var(--sp-3xl);
  }
  .sidenav { position: relative; height: auto; flex-direction: row; align-items: center; overflow-x: auto; padding: var(--sp-md); gap: var(--sp-sm); scrollbar-width: none; cursor: grab; }
  .sidenav::-webkit-scrollbar { display: none; }
  .sidenav.is-grabbing { cursor: grabbing; }
  .sidenav__brand, .sidenav__label, .sidenav__footer { display: none; }
  .sidenav__group { flex-direction: row; flex-wrap: nowrap; padding: 0; align-items: center; }
  .sidenav__item { white-space: nowrap; align-items: center; width: auto; }
  .sidenav__divider { width: 2px; height: 36px; margin: 0 var(--sp-md); background: var(--color-gold); border-radius: 1px; flex: 0 0 auto; opacity: 0.7; }
  .sidenav__scroll-cue {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    margin: 1px 0 calc(-1 * var(--sp-xs) - 5px); transform: translateY(-5px);
    font: 500 11px/1 var(--font-body);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-text-muted);
    user-select: none;
    pointer-events: none;
  }
  .sidenav__scroll-cue span:first-child,
  .sidenav__scroll-cue span:last-child {
    font-size: 14px;
    line-height: 1;
    color: var(--color-gold);
  }
  .workspace { padding: var(--sp-sm); }
  .section-nav-bar { margin: 0 calc(-1 * var(--sp-sm)) var(--sp-xl); padding: var(--sp-lg) var(--sp-sm) var(--sp-lg); }
  .section-nav { padding: var(--sp-md); }
  .workspace__title { font-size: 28px; }
  .form-grid { grid-template-columns: 1fr; }
  .tier-hero {
    grid-template-columns: 1fr;
    text-align: center;
    gap: var(--sp-lg);
  }
  .tier-hero__main { align-items: center; gap: var(--sp-lg); }
  .tier-hero__row {
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--sp-sm);
  }
  .tier-hero__row .tier-hero__label {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    font-size: 12px;
    text-align: center;
  }
  .tier-hero__meta { justify-content: center; }
  .tier-hero__actions {
    flex-direction: row;
    justify-content: center;
    align-items: center;
  }
}

@container vp (max-width: 767px) {
  .app { padding: 0 var(--sp-lg) var(--sp-3xl); }
  .workspace { padding: var(--sp-lg); }
  .section-nav-bar { margin: 0 calc(-1 * var(--sp-lg)) var(--sp-xl); padding: var(--sp-md) var(--sp-lg) var(--sp-lg); }
  .form-row { text-align: center; align-items: center; }
  .form-label { align-self: center; }
  .form-input,
  .form-select,
  .form-textarea { text-align: center; }
  .form-input::placeholder { text-align: center; }
}

@container vp (max-width: 599px) {
  .method {
    grid-template-columns: auto 1fr auto;
    gap: var(--sp-sm);
    padding: var(--sp-md);
    align-items: center;
    justify-items: stretch;
  }
  .method__brand { width: 48px; height: 32px; font-size: 10px; }
  .method__num { font-size: 14px; }
  .method__exp { font-size: 12px; }
  .method__actions {
    flex-direction: column;
    align-items: flex-end;
    gap: var(--sp-xs);
  }
  .method__actions .btn--subtle { padding: 4px 10px; font-size: 12px; min-height: 0; }
}

@container vp (min-width: 1024px) {
  .section .card,
  .section .tier-hero { max-width: 80%; margin-inline: auto; }
  /* S245 row 90 (Rob, the 7th of October 2026, on the Affiliate Bank details form: "why is there a big gap between the sort code and the account number fields? I mean
     technically if you can get them to line up with the edges of the name on the account field above, that would be even better."). MEASURED live at 1280 (and at 1920 the
     same way): this 80% sat on each FIELD, so the Name field was 477.4px wide while the Sort code and Account number fields were 236.3px each, centred in half-width rows, which
     put both of them 30.1px PAST the Name field's edges and left 65.1px between them. The bank form's fields now take the 80% on the GRID instead (the .form-grid rule below),
     so every field fills its own row: the Sort code starts on the Name field's left edge, the Account number ends on its right edge, and the gap is the grid's own 16px. The
     exclusion is :where(), which carries no specificity, so this rule keeps its specificity for every other form on the site. Below this width the form is already flush and is
     not touched. */
  .section .form-input:not(:where(.aff-bank-form .form-input)),
  .section .form-select,
  .section .form-textarea { max-width: 80%; margin-inline: auto; }
  .section .aff-bank-form .form-grid { max-width: 80%; margin-inline: auto; }
  /* the parent theme's Bootstrap gutter on .form-row (margin-inline: -5px, seeko theme-static.min.css) made each row 10px wider than its grid area, which ate 10px of the
     16px gap between the two lower fields and pushed every field 5px past the grid; off for this form so the grid's own edges and gap are the fields' edges and gap. */
  .section .aff-bank-form .form-row { margin-inline: 0; }
  .section .form-actions { max-width: 80%; margin-inline: auto; }
}

@container vp (min-width: 768px) and (max-width: 1023px) {
  .section .card,
  .section .tier-hero { max-width: 80%; margin-inline: auto; }
  #details .form-input,
  #details .form-select,
  #details .form-textarea,
  #payment .form-input,
  #payment .form-select,
  #payment .form-textarea,
  #billing .form-input,
  #billing .form-select,
  #billing .form-textarea,
  #security .form-input,
  #security .form-select,
  #security .form-textarea { max-width: 80%; margin-inline: auto; }
}

@container vp (min-width: 600px) and (max-width: 767px) {
  #details .form-input,
  #details .form-select,
  #details .form-textarea,
  #security .form-input,
  #security .form-select,
  #security .form-textarea,
  #billing .form-input,
  #billing .form-select,
  #billing .form-textarea { max-width: 80%; margin-inline: auto; }
}

@container vp (max-width: 599px) {
  .workspace__header { margin-bottom: calc(var(--sp-2xl) - 10px); }
  .section__heading { margin-top: -5px; }
  .form-actions { margin-top: 18px; }
  .app       { padding-inline: 5cqw; }
  .workspace { padding-inline: 0; }
  .section .card,
  .section .tier-hero,
  .section-nav-bar { width: 100%; max-width: none; margin-inline: 0; }
  .section-nav-bar { margin-inline: 0; padding-inline: 0; }
  .section-nav { width: 100%; }
}
/* end of 42.15 */

/* 42.16 Account toast — transient feedback notification for AJAX form saves */
/* S229 16/09/26 (T-S229-020): the Messages toast is raised with .account-toast--inpage, which
   pins it to the document at the point it appeared instead of the viewport, so it does not ride
   the scroll or sit over the footer. Every other surface keeps the fixed toast. */
.account-toast--inpage { position: absolute !important; right: auto !important; bottom: auto !important; }
.account-toast--account-form {
    position: static;
    right: auto;
    bottom: auto;
    width: fit-content;
    max-width: min(360px, 100%);
    margin: var(--sp-md) auto 0;
}
.account-toast {
    position: fixed;
    right: var(--sp-xl);
    bottom: var(--sp-xl);
    max-width: 360px;
    padding: var(--sp-md) var(--sp-lg);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    color: var(--color-navy);
    border: 1.5px solid var(--color-gold);
    box-shadow: var(--shadow-md);
    font: 600 14px/1.4 var(--font-body);
    z-index: 200;
    opacity: 0;
    transform: translateY(8px);
    pointer-events: none;
    transition: opacity var(--duration-fast) var(--ease-out),
                transform var(--duration-fast) var(--ease-out);
}
.account-toast[data-visible="true"] {
    opacity: 1;
    transform: translateY(0);
}
.account-toast[data-variant="ok"] {
    border-color: var(--color-success);
    background: #EAF4EC; /* S227 item 48: was rgba(39,166,68,0.08), so the footer read straight through the toast in Rob's photo. A floating notice has to be opaque. */
    color: var(--color-success);
}
.account-toast[data-variant="error"] {
    border-color: var(--color-error);
    background: var(--color-error-bg);
    color: var(--color-error);
}
/* end of 42.16 */

/* 42.17 Active sessions list (Security card) — matches design .toggle-row rhythm */
.sessions-list {
    list-style: none;
    margin: 0 0 var(--sp-md);
    padding: 0;
    display: flex;
    flex-direction: column;
}
.sessions-list__item {
    padding: var(--sp-md) 0;
}
.sessions-list__item + .sessions-list__item {
    border-top: 1px solid var(--color-border);
}
.sessions-list__item { text-align: center; }
.sessions-list__main {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    min-width: 0;
}
/* R3-07 24/09/2026, Rob (item 7): the THIS DEVICE pill stacks on its own line ABOVE the
   device line, same uniform gap as the title-to-meta gap below (.sessions-list__main's own
   2px, matched here so both gaps read the same). column-reverse keeps DOM/reading order
   ("Chrome on Windows", then "This device") while painting the pill first, so nothing is
   deleted or reordered in the markup, only the visual stack direction changes. */
.sessions-list__title {
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 14px;
    color: var(--color-navy);
    display: flex;
    flex-direction: column-reverse;
    align-items: center;
    justify-content: center;
    gap: 2px;
    flex-wrap: wrap;
}
.sessions-list__meta {
    font-size: 13px;
    color: var(--color-text-secondary);
}
.sessions-list__current-pill {
    /* Padding corrected INK-ROBUST-2 25/09/2026, same reasoning as .tier-badge above: 0.381px
       at raster (a) (412w dpr2.625) is one whole device pixel at Rob's own density. Bracketed
       at raster (a) in 0.25px steps, sum held within 1px of the original 4.5px: 2.5px/1px
       (sum 3.5) lands dy 0.19, -0.167, -0.25, -0.125px on all four canonical rasters (412w
       dpr2.625, 360w dpr3, 360w dpr2, 360w dpr8) - results/s235/ink-robust/. */
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    background: var(--color-cream);
    color: var(--color-navy);
    border: 1px solid var(--color-gold);
    padding: 2.5px 8px 1px;
    border-radius: var(--radius-pill);
}
/* end of 42.17 */

/* 42.18 Security cards — uniform vertical rhythm.
   Rob override: every gap inside a security card (top→first child, child→child, last child→bottom) must equal the card padding. */
#security .card {
    display: flex;
    flex-direction: column;
    gap: var(--sp-xl);
}
#security .card > * {
    margin-block: 0 !important;
}
#security .card.card--centered .toggle-row {
    gap: var(--sp-xl) !important;
}
/* Centre every action button within security cards (overrides default flex-end / flex-start). */
#security .card .form-actions,
#security .card .form-actions--start {
    justify-content: center !important;
}
/* end of 42.18 */

/* 42.19 Payment-methods card — left-align the num/exp middle column next to the brand badge. */
.workspace .method > div:nth-child(2) {
    text-align: left;
}
/* end of 42.19 */

/* 42.20 Read-only Country field — match .form-input visual but non-interactive. */
.workspace .form-input--readonly {
    cursor: default;
    user-select: none;
    color: var(--color-navy);
    text-align: center;
}
/* end of 42.20 */

/* 42.21 Restore sidenav labels at narrow viewports.
   Legacy profile-editor.css §15.5.4 has `.sidenav-label { display: none }` inside @media (min-width:768px)and(max-width:1023px). Our new BEM label spans carry both classes (`sidenav-label sidenav__item-label`), so the legacy rule hides them. The design's pill-style horizontal sidenav at narrow widths shows icon + label — restore that. */
@media (min-width: 768px) and (max-width: 1023px) {
    .sidenav__item-label {
        display: inline !important;
    }
}
/* end of 42.21 */

/* 42.23 ONE dashboard-to-footer gap, the same on every dashboard page at every width.
   R3-12 and R3-21 (Rob, 24/09/2026, from his phone): the Account tabs ended about 5px above
   the footer; "it should be 30 or 40 pixels ... check all the dashboard pages because they
   should all be the same". The gap is the footer's own top margin: 30px per S228 item 19
   ("reduced the footer's top margin to 30 pixels and leave it at that"), raised to 50px by
   R3-12 (Rob, 24/09/2026: "make it 50"), so the dashboard adds nothing below its last block:
   no bottom padding on the shell
   or the main column, no trailing margin or empty padding on the last block, and nothing
   pulling the column up. The phone rule this replaces pulled the column up 24px to cancel a
   tail only the Dashboard tab had, so on every other tab it ate 24 of the footer's 30px and
   left the 6px Rob photographed. */
body.profile-dashboard-active:not(.profile-editor-active) .app {
    padding-bottom: 0 !important;
}
.account-toast.account-toast--account-form {
    position: static;
    right: auto;
    bottom: auto;
    width: fit-content;
    max-width: min(360px, 100%);
    margin: var(--sp-md) auto 0;
    /* S238 STYLE (Rob, the 27th of September 2026: "make sure all text is centred"): the box was centred but its text
       was not, so a message that wraps (the server refusals F19 routes here, and every message at 360) read ragged left. */
    text-align: center;
}
body.profile-dashboard-active:not(.profile-editor-active) .workspace > .section {
    margin-bottom: 0 !important;
}
body.profile-dashboard-active:not(.profile-editor-active) .workspace {
    padding-bottom: 0 !important;
}
/* The last block on a tab ends the page, so the space that separates it from a next block has
   nothing below it to separate: the last Dashboard section (36px), the last Attendance, Events
   or Invites card (24px) and the last My Interests panel (24px) end flush, and so does the
   empty-feed message's own 32px under the last Dashboard section. */
body.profile-dashboard-active:not(.profile-editor-active) .dashboard-feed-container > .dash-section:last-of-type,
body.profile-dashboard-active:not(.profile-editor-active) .workspace > .att-section:last-of-type,
body.profile-dashboard-active:not(.profile-editor-active) .workspace > .mi-section:last-of-type {
    margin-bottom: 0;
}
body.profile-dashboard-active:not(.profile-editor-active) .dashboard-feed-container > .dash-section:last-of-type .event-empty {
    padding-bottom: 0;
}
body.profile-dashboard-active:not(.profile-editor-active) #item-body,
body.profile-dashboard-active:not(.profile-editor-active) .bp-member-layout > .container,
body.profile-dashboard-active:not(.profile-editor-active) .bp-member-layout {
    padding-bottom: 0 !important;
    margin-bottom: 0 !important;
}
/* end of 42.23 */

/* 42.24 Invoice stack at narrow — verbatim from design styles.css:1206-1273.
   At ≤599 the table is hidden and the .invoice-stack card list shows. */
@container vp (max-width: 599px) {
    .invoice-scroll,
    .invoice-scroll__hint { display: none; }
    .invoice-stack {
        display: flex;
        flex-direction: column;
        gap: var(--sp-md);
        list-style: none;
        margin: 0;
        padding: 0;
    }
    .invoice-stack__item {
        display: grid;
        grid-template-columns: 1fr auto;
        column-gap: var(--sp-md);
        row-gap: var(--sp-sm);
        padding: var(--sp-2xl);
        border: 1.5px solid var(--color-gold);
        border-radius: var(--radius-md);
        background: var(--color-surface);
    }
    .invoice-stack__date {
        grid-column: 1 / -1;
        text-align: center;
        font-family: var(--font-heading);
        font-weight: 700;
        color: var(--color-navy);
        font-size: 14px;
    }
    .invoice-stack__item > .invoice-status {
        grid-column: 1 / -1;
        justify-self: center;
    }
    .invoice-stack__body {
        grid-column: 1 / -1;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: var(--sp-xs);
    }
    .invoice-stack__desc {
        color: var(--color-navy);
        font-size: 14px;
    }
    .invoice-stack__amount {
        font-family: var(--font-heading);
        font-weight: 700;
        color: var(--color-gold);
        font-size: 14px;
        white-space: nowrap;
    }
    .invoice-stack__download {
        grid-column: 1 / -1;
        justify-self: stretch;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: var(--sp-xs);
    }
}
/* end of 42.24 */

/* 42.25 Danger-row narrow collapse — verbatim from design styles.css:1391-1400. */
@container vp (max-width: 600px) {
    .danger-row {
        grid-template-columns: 1fr;
        justify-items: center;
        text-align: center;
        gap: var(--sp-md);
        padding: var(--sp-lg) 0;
    }
    .danger-row__title, .danger-row__hint { text-align: center; }
}
/* end of 42.25 */

/* 42.26 Scroll-cue text colour — Rob override of spec (spec sets middle text to muted-navy 55%; Rob wants whole cue gold). */
.sidenav__scroll-cue {
    color: var(--color-gold) !important;
}
/* end of 42.26 */

/* 42.30 Save billing — Save above Cancel, both centered, GLOBAL across all
   widths (Rob override of spec which only does this at narrow).
   S198 29/08/26 — the asymmetry Rob flagged at the end of S89 (T609) is CLOSED,
   and it was not the margins. Measured on all three stacked pairs (Account
   details, Security, Billing): the two buttons are the same 220px wide and both
   dead centre, but `.btn--subtle` renders 25px tall against `.btn--primary`'s
   39px - a 14px mismatch in a centred stack, which is what reads as lopsided.
   Cause: --subtle carries `padding: 6px 8px` at 13px type with no border, while
   --primary carries `padding: 10.5px 24px` (11/10 until S198) at 14px with a 2px border. The two
   were never meant to stack.
   Equalised HERE, in the rule that owns the stack, rather than by editing
   `.btn--subtle`, whose 6px padding is correct everywhere it is used inline. The
   --primary padding's own 11px/10px top-bottom split is left alone: it is the
   optical correction for Montserrat caps riding high in the em-box, not an
   error. */
.workspace .form-actions {
    flex-direction: column-reverse !important;
    align-items: center !important;
    justify-content: center !important;
    gap: var(--sp-sm) !important;
    margin-top: var(--sp-xl) !important;
}
.workspace .form-actions .btn {
    width: auto !important;
    min-width: 220px !important;
    min-height: 39px !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    box-sizing: border-box !important;
}
/* FF02-15: verified account-page action buttons use the standard cream/gold
   save face, white/gold reset face and the same subtle gold lift. */
#details .form-actions .btn {
    box-shadow: var(--shadow-gold-hover) !important;
}
#details .form-actions button[type="submit"] {
    background: var(--color-cream, #FFFBE6) !important;
    border-color: var(--color-gold, #CC9900) !important;
    color: var(--color-navy, #031B83) !important;
}
#details .form-actions button[type="reset"] {
    background: #FFFFFF !important;
    border-color: var(--color-gold, #CC9900) !important;
    color: var(--color-navy, #031B83) !important;
}
#details .form-actions button[type="submit"].is-save-ok {
    background: var(--color-success-bg, rgba(39, 166, 68, 0.08)) !important;
    border-color: var(--color-success, #27A644) !important;
    color: var(--color-success, #27A644) !important;
}
/* end of 42.30 */

/* 42.31 S92 #37 — 2FA workspace setup (inline, replaces wp-admin redirect).
   Two subviews inside Security section: 'default' (4 cards) and '2fa-setup'.
   View toggled via [data-view] attribute on .security-views. */
.security-views[data-view="default"] .security-view--2fa-setup { display: none; }
.security-views[data-view="setup"] .security-view--default { display: none; }

.workspace .setup-2fa-header {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sp-sm);
    margin-bottom: var(--sp-xl);
}
.workspace .setup-2fa-header .btn--ghost {
    align-self: flex-start;
}
.workspace .setup-2fa-title {
    font-family: var(--font-heading);
    color: var(--color-navy);
    font-size: 22px;
    font-weight: 700;
    margin: 0;
    text-align: center;
}

.workspace .setup-2fa-card { margin-bottom: var(--sp-lg); }

.workspace .setup-2fa-qr {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sp-md);
    margin: var(--sp-md) auto;
}
.workspace .setup-2fa-qr-target {
    min-width: 180px;
    min-height: 180px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #FFFFFF;
    border: 2px solid var(--color-gold, #CC9900);
    border-radius: var(--radius-md, 16px);
    padding: var(--sp-sm);
}
.workspace .setup-2fa-qr-target img {
    display: block;
    max-width: 180px;
    height: auto;
}
.workspace .setup-2fa-secret-wrap { text-align: center; max-width: 360px; }
.workspace .setup-2fa-secret {
    display: inline-block;
    font-family: 'Courier New', monospace;
    font-size: 13px;
    background: #fffbe6;
    border: 1px solid var(--color-gold, #CC9900);
    border-radius: 8px;
    padding: 6px 12px;
    color: var(--color-navy, #031B83);
    letter-spacing: 1px;
    word-break: break-all;
    max-width: 100%;
}

.workspace .setup-2fa-verify { text-align: center; margin-top: var(--sp-md); }
.workspace .setup-2fa-verify-row {
    display: flex;
    flex-direction: column;
    gap: var(--sp-sm);
    align-items: center;
    justify-content: center;
    margin: var(--sp-sm) auto 0 auto;
    width: fit-content;
}
.workspace .setup-2fa-code-input {
    width: 220px !important;
    max-width: 220px !important;
    text-align: center;
    font-size: 20px;
    letter-spacing: 4px;
    font-family: 'Courier New', monospace;
    margin: 0 auto !important;
}
.workspace .setup-2fa-msg {
    margin-top: var(--sp-sm);
    font-size: 14px;
    color: var(--color-navy, #031B83);
    min-height: 1.4em;
}

.workspace .setup-2fa-status { text-align: center; margin: var(--sp-md) 0; }

.status-pill {
    display: inline-block;
    padding: 4px 12px;
    border-radius: 9999px;
    font-family: var(--font-heading);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.3px;
    text-transform: uppercase;
}
.status-pill--success {
    background: rgba(39, 166, 68, 0.12);
    /* S245 S9-61: the text was #1e7a32, a dark green of its own that is in no brand guide. It is the token green now, --color-success (#27A644), as the green
       tick badge (D-181, 41.8 above) and the good-password line (S238 X06b) already are. */
    color: var(--color-success);
    border: 1px solid rgba(39, 166, 68, 0.4);
}

.workspace .setup-2fa-recovery-status { text-align: center; margin-bottom: var(--sp-md); }
.workspace .setup-2fa-recovery-codes { max-width: 360px; margin: var(--sp-md) auto; }
.workspace .recovery-codes-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
}
.workspace .recovery-codes-list li { text-align: center; }
.workspace .recovery-codes-list code {
    display: block;
    font-family: 'Courier New', monospace;
    font-size: 14px;
    background: #fffbe6;
    border: 1px solid var(--color-gold, #CC9900);
    border-radius: 6px;
    padding: 8px 10px;
    color: var(--color-navy, #031B83);
    letter-spacing: 1px;
}
.workspace .setup-2fa-recovery-warn {
    text-align: center;
    /* S207 05/09/26, Rob: brown text is not a brand colour. "it's blue or gold and that's it."
       Was #856404. */
    color: var(--color-navy);
    font-size: 13px;
    margin-top: var(--sp-sm);
}
/* end of 42.31 */

/* end of 42 */

/* 43 SECTION: Universal Button System (S100, 25/05/26 — D-174 v2)
   ==========================================================================
   Three canonical button classes that every button on the site uses. Each
   button keeps its existing specific class (so JS bindings work unchanged)
   and gains ONE of these three base classes via the page-by-page sweep.

   - .btn-option    — public-site default. View venue, View profile, Show
                       Interest, Save venue, Reserve my spot, form submits,
                       all non-dashboard non-menu buttons. Size variant
                       .btn-option--lg for big CTAs (Reserve my spot etc.).
   - .btn-dashboard — every button inside the dashboard / personal pages.
   - .btn-menu      — dashboard sub-section navigation tabs.

   Shadow language (uniform across all three):
   - Rest:        navy 2-layer drop @ 10% opacity
   - Hover:       bigger navy 2-layer drop @ 12-14% + translateY(-1px)
   - Menu active: NO shadow (= "pressed in" / currently selected)
   - Disabled:    NO shadow, greyed-out

   Spec source of truth: docs/BRAND_GUIDE.md — Buttons section.
   ========================================================================== */

/* 43.1 .btn-option — public-site default button.
   !important on visual properties to defeat Seeko parent theme's broad
   `.btn, input[type=submit], ..., button { ... }` rule which uses !important
   and wins on source order otherwise. Vertical-alignment of text is enforced
   via line-height + align-items so any two buttons placed side-by-side share
   the same text-baseline visual centre — required by the universal vertical-
   alignment design rule. */
/* S217 (S217-V2, Rob 09/09/26): the venue card's Show Interest button never carried
   .btn-option, so it fell through to the parent theme (grey fill, no border, Nunito Sans
   400, no shadow) while the organiser card's identical control looked right. Rob: "it looks
   far better on the organiser cards". Joining the canonical selector is the fix; a separate
   rule for .venue-save-btn would be a second source of truth for the same button. */
/* S245 row K (FAULTS row 6, Rob 06/10/26: "Log in and join now should be proper buttons", the cream box at the bottom of /events/). The two anchors of the
   logged-out call-to-action box (.events-login-cta, mu-plugins/event-system.php 10.1.4) carry no class, so they join the canonical selector exactly as
   button.venue-save-btn did in S217 above: one source of truth for the button and no second copy of its values. The rules that were wrong, the gold
   underlined text link painted by the inline .events-login-cta a rules (functions.php, "Login CTA", and mu-plugins/event-system.php), lose on every property because
   this block states them all with !important. The hover and pressed rules below take the same selector. */
.btn-option,
button.venue-save-btn,
.events-login-cta p > a {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    align-self: center !important;
    gap: 6px !important;
    padding: 7px 12px !important;
    border-radius: 10px !important;
    font-family: var(--font-heading) !important;
    font-weight: 700 !important;
    font-size: 12px !important;
    line-height: 1.2 !important;
    letter-spacing: 0.02em !important;
    background: transparent !important;
    color: var(--color-navy) !important;
    border: 1px solid var(--color-gold) !important;
    box-shadow: var(--shadow-gold-hover) !important;
    cursor: pointer !important;
    text-decoration: none !important;
    text-transform: none !important;
    white-space: nowrap !important;
    margin: 0 !important;
    transition: background-color 120ms ease-out, box-shadow 120ms ease-out, transform 120ms ease-out !important;
}
.btn-option:hover,
button.venue-save-btn:hover,
.events-login-cta p > a:hover {
    background: var(--color-cream) !important;
    color: var(--color-navy) !important;
    border-color: var(--color-gold) !important;
    /* S245 row 130 (Rob, the 9th of October 2026: "the drop shadows are so completely different between these buttons ... check which ones actually correct and make sure they all
       have them"). THE ONE SHADOW. This hover carried a two-layer lift (0 4px 4px + 0 8px 18px, R3-32 and then D-655 turning its gold to black) that no other button family on the site
       has: READ OFF the signed-off dashboard buttons with a real pointer as a member (Prev and Next, Randomise, Profile and Customise, the calendar arrows, and the Messages .btn--primary
       and .btn--danger Rob passed in rows 112 and 119), the hovered shadow is the rest shadow, `0 4px 12px rgba(0,0,0,.16)` (--shadow-gold-hover, D-640 and D-655), unchanged, with the
       lift where the family lifts. So a hovered .btn-option showed a shadow half as large again as the same button's neighbours at rest and as every .btn--primary and .btn--danger.
       It now keeps the one shadow; the cream (white or transparent at rest to --color-cream here, as D-512 ruled for this family) and the 1px lift are as they were. */
    box-shadow: var(--shadow-gold-hover) !important;
    transform: translateY(-1px) !important;
    text-decoration: none !important;
}
/* S245 row 130, the pressed state (D-640: "pressed and in-flight: darker cream #FFF5CC with no shadow"). .btn-option never had one: a button held down painted its hover (the lift and
   the shadow, MEASURED live on the event card's Report held down: transform translateY(-1px), the two-layer shadow, #FFFBE6), while every other site button goes to the darker cream
   with no shadow and no lift (.btn--primary:active, 42.8; the dashboard buttons, measured). It is stated after the hover rule at the same specificity so it wins while both match
   (:where() keeps the :not() guards out of the count: 0,2,0 against the hover rule's 0,2,0), and the green selected states (.btn-option--select.active, .wishlist-active), which
   are three-class rules below, outrank it and stay green. */
.btn-option:active:where(:not(:disabled):not(.is-disabled)),
button.venue-save-btn:active:where(:not(:disabled)),
.events-login-cta p > a:active {
    background: var(--color-cream-hover) !important;
    color: var(--color-navy) !important;
    border-color: var(--color-gold) !important;
    box-shadow: none !important;
    transform: none !important;
}
/* S245 row K, the call-to-action row. The second paragraph of .events-login-cta holds Log in, the word "or" and join now. It becomes one centred line with the
   two buttons and the word on a SHARED BASELINE, 10px between them (the gap of .uks-card__actions, 52.1: the pair of buttons Rob signed off on the same page),
   and it wraps instead of overflowing on a narrow phone. Baseline, not centre: MEASURED from the painted pixels at 8x, with align-items:center the word "or" sat
   1.06px below the buttons' midline (its ink is the x-height band, which hangs below the middle of its line box); on the shared baseline it sits 0.06px off the
   midline, at 1280 and at 360. The box itself (cream ground, 2px gold border, radius, width, type, the first sentence) stays exactly as the inline
   .events-login-cta rules in functions.php paint it. */
.events-login-cta p:last-child {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: center;
    gap: 10px;
}
/* S245 row K, the two anchors, the two things .btn-option's own block cannot give them here, both stated with !important because that block is armoured with it
   against the parent theme (BRAND_GUIDE 9.7 point 4 allows the scoped bump and leaves the base rule alone; the card buttons do the same at 52.4).
   (1) align-self: .btn-option says center, which would take the buttons out of the shared baseline above.
   (2) The label's ink. COPIED, not invented: the card family's own two values (R3-33c GATE 12 at the end of this file, .uks-card__actions .uks-card__btn: 7.7px
   above and 6.3px below, the same 14px in total as .btn-option's 7px and 7px, so the height stays 30.4px and only the label moves). MEASURED with the comparison
   gate's own read (capital top to baseline from the rendered font, against the button's box): the label sat 0.695px HIGH at 1280 with 7px and 7px, and reads +0px
   with these two values at 1280 and at 360. From the painted pixels at 8x the capital band is 0.315px above the painted midline with either pair (the painted label
   did not move for a 0, 0.5 or 0.7px shift and moved a whole pixel at 1.0px), inside the 0.5px tolerance. */
.events-login-cta p:last-child > a {
    align-self: baseline !important;
    padding-top: 7.7px !important;
    padding-bottom: 6.3px !important;
}
/* S245 item 56 (S9-3, the 16th of September list line 120: "Five dark gold buttons on the marketing pages break the all-cream rule"; D-512, every button on the site is the site's
   button). The five buttons are the page builder's own (a.uksp-button.uksp-button-link inside .uksp-widget-button): SIGN UP on /about-us/, and SIGN UP, EVENTS, Pricing and Sign Up on
   /home-page/. They were solid gold (#CC9900) with a white label, no border and 3px corners, beside the Pricing SELECT and Contact SEND MESSAGE buttons, which are the site's cream button.
   WHAT PAINTED THEM, read off the live page with the browser's own matched-rules list, logged out, at 1280 and 360: no rule in this file or in style.css reaches these anchors. The gold is
   the page builder's per-widget CSS, which ships as static files that are the builder's own output and are not edited here: assets/uks-static/pages/inline-about.css line 3
   (.uksp-926 .uksp-element.uksp-element-7d773c1 .uksp-button, background-color the builder's gold) and assets/uks-static/pages/inline-home.css lines 19 and 23 (the same selector shape for the
   four home widgets, the SIGN UP widget also border-style: none), over the builder's base .uksp-button in assets/uks-static/up/css/custom-frontend.min.css line 1 (grey ground, 3px corners,
   white label, 12px 24px padding; its :hover, :focus and :visited also paint the label white) and .uksp-animation-grow:hover in
   assets/uks-static/el/lib/animations/styles/ukse-animation-grow.min.css (a 1.1 scale-up on hover and focus). The widget rules weigh 0,4,0 at most and the others less, so the rule below,
   0,5,1 at rest and 0,6,1 for hover and pressed, outranks all of them whichever sheet loads last. It names the buttons by the builder's own classes, never by a bare element, and reaches no
   other button on the site: assets/uks-static/pages/inline-about.css and inline-home.css are the only two builder page files that style a .uksp-button.
   THE VALUES, COPIED and never invented: the cream ground #FFFBE6 (--color-cream), the 1px gold border (--color-gold) and the navy label (--color-navy) are the Pricing SELECT button's, read
   live (a.card-btn on /pricing/ paints #FFFBE6, 1px solid #CC9900, #031B83); the 10px corners are D-508; the label typeface is --font-heading (Montserrat), the face of .btn-option above and of
   the SELECT button, which the three buttons the builder had set in Nunito Sans (About us SIGN UP, home Pricing, home Sign Up) now take; the shadow is --shadow-gold-hover
   (0 4px 12px rgba(0,0,0,.16)), held at rest by .btn-option above and by the SELECT button; the hover is the darker cream #FFF5CC (--color-cream-hover, the SELECT button's hover) with that same
   shadow and the 1px lift of .btn-option:hover; the pressed state is .btn-option:active above, the darker cream with no shadow and no lift; the transition is .btn-option's. The builder's 1.1 grow
   is stood down in every state (transform: none at rest, translateY(-1px) on hover, none while pressed). Size, weight, case and padding stay as each widget sets them (D-512: button padding
   waits until after launch). */
.uksp .uksp-element.uksp-widget-button a.uksp-button.uksp-button-link {
    background-color: var(--color-cream);
    color: var(--color-navy);
    border: 1px solid var(--color-gold);
    border-radius: 10px;
    font-family: var(--font-heading);
    box-shadow: var(--shadow-gold-hover);
    transform: none;
    transition: background-color 120ms ease-out, box-shadow 120ms ease-out, transform 120ms ease-out;
}
.uksp .uksp-element.uksp-widget-button a.uksp-button.uksp-button-link:hover {
    background-color: var(--color-cream-hover);
    color: var(--color-navy);
    border-color: var(--color-gold);
    box-shadow: var(--shadow-gold-hover);
    transform: translateY(-1px);
}
.uksp .uksp-element.uksp-widget-button a.uksp-button.uksp-button-link:active {
    background-color: var(--color-cream-hover);
    color: var(--color-navy);
    border-color: var(--color-gold);
    box-shadow: none;
    transform: none;
}
/* S245 item 56, the About us SIGN UP button only. Its widget sets line-height: 1.6px (assets/uks-static/pages/inline-about.css line 3, a stray unit: the builder's base .uksp-button has line-height: 1,
   which the four home buttons keep), so its label sits in a 1.6px line box between 1rem of padding top and bottom, and the label's capital band lands above the button's midline. MEASURED on the
   live page in the cream button, at 1920, 1280, 1024, 768 and 360: the comparison engine's own read (capital top to baseline from the rendered font, against the button's box) was -0.797, -0.797,
   -0.297, -0.297 and -0.797, and the painted pixels at 8x (the first capital's top and bottom against the button's midline) read -0.83, -0.57, +0.06, -0.19 and -0.91; the engine refuses a label that
   is not centred by ink (0.5px). A 1px padding shift centres 1920, 1280 and 360 but pushes 1024 and 768 to +0.70 on the engine's measure and +1.06 and +0.81 painted, and the half pixel the engine
   would accept moves the painted label at only some widths. So the line-height goes back to the builder's base 1 and the vertical padding becomes 0.375rem + 0.8px each side, which keeps the button
   exactly as tall as the widget makes it (2rem of padding and a 1.6px line is 0.75rem + 1.6px of padding and a 1.25rem line, plus the border) and gives it the structure of the four home buttons.
   Read after, the engine measure is -0.25, -0.25, -0.125, -0.125 and 0, and the painted offset +0.18, +0.43, +0.06, -0.19 and +0.10, at the same five widths. The other four buttons read at or inside
   0.5px on the engine measure at every width. */
.uksp .uksp-element.uksp-element-7d773c1 a.uksp-button.uksp-button-link {
    line-height: 1;
    padding-top: calc(0.375rem + 0.8px);
    padding-bottom: calc(0.375rem + 0.8px);
}
/* S222 items 3, 16, 43 and 109 (Rob, 14/09/2026). THE ONE IN-FLIGHT TREATMENT.
   Rob on the attendance Saving button: "I do not like saving looking all grey when it is
   processing... Saving should be shown the same everywhere and it should not grey out. You can
   use whatever has been verified somewhere else in the site as the token styling." On the bank
   details one: "the contrast needs to be brought up to the 75% or whatever it is."
   MEASURED BEFORE, from the painted pixels at deviceScaleFactor 4, not from computed styles:
   the bank Saving button and the attendance Saving button both painted rgb(183,190,219) on
   rgb(246,247,251), a contrast of 1.72 to 1. The report modal Submitting button painted
   rgb(199,205,227) on rgb(248,249,252), 1.50 to 1. WCAG AA for text is 4.5 to 1.
   WHY IT WAS SO FAR OUT. Three declarations here wiped the button (6% navy ground, 40% navy
   label, transparent border) AND Seeko's own button:disabled fades the whole element to
   opacity .65 on top of that, so the 40% label painted at an effective 26%. Opacity applies to
   the group, so no descendant can opt out of it: that is the same trap recorded on the customise
   Save Design button (LB-334).
   THE TREATMENT is the one already verified on this site at 46.Z, in its own words: "Disabled
   state - visually IDENTICAL to the active state. The JS disables the button during AJAX as a
   guard against double-clicks... No dim, no opacity... the text change alone is the feedback."
   The button keeps its own cream, its own gold border and its own navy label; only the shadow
   goes, so it does not read as pressable, and the cursor still says not-allowed. Same again at
   34.1, where the Reported state was taken off grey on 14/09/2026 for the same reason.
   MEASURED AFTER: bank Saving 13.57 to 1, attendance Saving 14.11 to 1, report Submitting
   13.57 to 1, all on the real pages with the real markup.
   opacity is pinned to 1 because Seeko's rule is what put the group fade there. */
/* S227 item 12 (Rob: "I believe we've been using 65% or 75% - check other examples").
   The Family and Friends Request button is a bare <button> with no .btn-option class, so
   nothing of ours reached it and the parent theme's own button:disabled opacity of .65 was left
   to paint it. MEASURED LIVE 15/09/2026, in flight: opacity 0.65, painted 3.45 to 1 at 360 and
   4.73 to 1 at 1280, against 14.11 to 1 for the two buttons beside it on the same panel. It
   joins the one in-flight rule here rather than getting a rule of its own; the member's
   feedback is unchanged, family-link.php still writes "Sending request..." beside it. */
/* S227 Q35: remove Seeko's blanket 65% fade from every disabled action.
   The pagination arrows keep their explicit 30% rules below. */
/* S232 21/09/2026, Rob correction row 13, with his own screenshot of the customise page: "why
   does it look like that? It looks like it doesn't have a gold border?" MEASURED during a real
   save on /members/cold_prem19/customise/: the button painted #FFFBE6 with no edge at all, and
   this rule was the winner at specificity (0,6,1) over .btn-save:disabled at (0,2,0). The intent
   written above is "keeps its own cream, its own gold border ... only the shadow goes", but that
   toolbar draws its gold border AS an inset box-shadow, so box-shadow:none took the border with
   it. .btn-save is excluded here and profile-editor.css .btn-save:disabled carries the same four
   declarations for it, with the gold edge kept and the outer shadow still gone. It is the only
   button on that toolbar the editor ever disables (profile-grid.js 2687). */
/* Row 8 (S245 09/10/26): the dashboard Prev / Next buttons are excluded here for the same reason .btn-save is above.
   This rule took the shadow off EVERY disabled button, and the JS disables both week buttons while the week loads, so
   the one the member did not click lost its shadow too. They carry their own in-flight rule at 46.Z further down. */
button:disabled:not(.att-pagination__btn):not(.wl-pagination__btn):not(.ev-pagination__btn):not(.sg-pagination__btn):not(.mi-pagination__btn):not(.btn-save):not(.dashboard-week-nav-btn),
.btn-option:disabled,
.btn-option.is-disabled,
button.venue-save-btn:disabled,
.uks-family-request-btn:disabled {
    opacity: 1 !important;
    box-shadow: none !important;
    cursor: not-allowed !important;
    transform: none !important;
}
/* Size variant — large CTAs like "Reserve my spot". Sized to match the existing
   live Reserve my spot button (which Rob has signed off as the canonical size). */
.btn-option--lg {
    font-size: 14px !important;
    /* S198: Rob reads the label as sitting below the centre line even with the box
       measuring 12px above and 12px below, so it is lifted a pixel - 10px above, 12px
       below. Box height is unchanged at 40px; only the label moves. */
    padding: 10px 20px 12px !important;
    /* S198 29/08/26 (Rob spotted the label sitting off-centre): 14px at the inherited
       line-height 1.2 gives a 16.8px line box, so this button measured 40.797px tall - a
       FRACTIONAL height, so the label could never sit level. Pinned to a whole 16px, which
       is the font box itself: with symmetric 11px padding and a 1px border the box is 40px
       and the label has exactly 12px above and below.
       NOTE the parity here is the OPPOSITE way round to the calendar rings (/da rule 21b).
       A ring is painted ON the box, so it needs an ODD box to share a centre row with the
       ink inside it. A button label is centred BETWEEN the box edges, so what matters is
       that the leftover space divides in two - an odd leftover is what splits 12/13. Tried
       17px first and got exactly that. */
    line-height: 16px !important;
}
/* 43.1.1a .btn-option--cta — EMPHASIS variant. Same shape, size and border as the
   base; the only change is a cream fill at rest so a page's single primary call to
   action stands out from the transparent buttons around it. Rob, 29/08/26, on the
   directory CTA: "make that register your venue button one of the light cream ones
   as well so it's a bit more noticeable."

   Both colours are the documented brand tokens, not new values: rest is the D-084 /
   LB-023 canonical cream (#FFFBE6, `--color-cream`) and hover steps to
   `--color-cream-hover` (#FFF5CC) — exactly the pair `.btn-dashboard` uses, so a
   cream button behaves the same wherever it appears. Base `.btn-option` hovers TO
   cream, so without this the emphasis variant would have had nowhere to go on hover.

   Use on ONE button per page. If everything is cream, nothing is emphasised. */
.btn-option--cta {
    background: var(--color-cream) !important;
}
.btn-option--cta:hover {
    background: var(--color-cream-hover) !important;
}
/* 43.1.2 .btn-option--select — selection variant for option buttons used as
   radio-style multi-choice (e.g. "pick one of these options"). On .active the
   button takes the green selection treatment that matches the toggle is-checked
   state used by checkbox toggles (No screens / Business only). Rob 28/05/26:
   "let's have it as a 'selection' option variant for things like this where it
   is for choosing from a bunch of options." Add `.btn-option--select` to any
   `.btn-option` button group that behaves as a single-selection picker; JS
   should toggle `.active` on the chosen one (and remove from siblings).
   Sequenced transition — depress (shadow + transform clear) first ~0.1s, then
   the colour swap kicks in over 0.15s after a 0.1s delay, so the press reads
   visually as press-then-confirm rather than colour-change-then-depress. */
/* S217 (S217-V1, Rob 09/09/26): showing interest is a confirmed positive state, and the
   platform already has one - this selection green, the same the checkbox toggles use when
   they are on. Rob: "they should use the greens instead to show the positive state". The
   Interested control on venue cards, organiser cards and member profiles joins it rather
   than getting a green of its own. */
/* S238 F31 (Rob, 26/09/2026: an event you hold a ticket or place for "stays in your list and its
   card shows you have a ticket"). The event card's "You have a ticket" state (event-system.php
   10.2, .uks-card__btn--going) is the same confirmed positive state, so it joins this one green
   rather than getting its own. Two classes so it outranks .btn-option and .btn-option:hover
   (12049, 12074), which are armoured with !important. Size, radius, padding and the nowrap label
   all stay .btn-option's and the card button's own (52.1, 52.4, R3-33c GATE 12). */
/* S245 (item 88, "the green Message button"; Rob's S227 question 34 default: "Make it white, per your ruling" that those buttons are white). The Message button inside a venue or
   organiser widget (`a.vw-owner-msg`, venue-organiser-widgets.php 489 and 1031) carries `wishlist-active` in its class list, so this rule painted it the positive green
   (MEASURED live, example_kate_yeo venue_contact_hours at 1280 and 360, in the editor and on the public profile alike: background rgb(234,244,236), 2px rgb(47,125,79) edge,
   rgb(47,107,71) label, no shadow). It is not a chosen or confirmed state, it is the widget's one action, so it is excluded here at the legacy selector (this rule and the two
   that follow), with :where() so no specificity moves; the base `.btn-option` look then applies. */
.btn-option--select.active,
.btn-option--select.active:hover,
.wishlist-button.wishlist-active:not(:where(.vw-owner-msg)),
.wishlist-button.wishlist-active:not(:where(.vw-owner-msg)):hover,
.uks-card__btn.uks-card__btn--going,
.uks-card__btn.uks-card__btn--going:hover {
    /* S217 (D-499, Rob 09/09/26 "make sure they match the preferences styling"): this variant
       carried its own green (#f0faf1 / #2d6a2e) while the preferences questionnaire used
       #EAF4EC / #2F7D4F / #2F6B47. Three points apart and invisible side by side, but two
       sources of truth for one meaning. The preferences values win, so every positive state on
       the platform - a picked option, a shown interest, a checked chip - is now one colour. */
    background: #EAF4EC !important;
    border-color: #2F7D4F !important;
    color: #2F6B47 !important;
    box-shadow: none !important;
    transform: none !important;
    /* S230 17/09/2026, Rob: "It should depress... and it should change to green... And it
       should all happen at the same time, but something else seems to happen first." The
       sequence above was deliberate (press first, colour 0.1s later) and he has now ruled
       against it: every property changes together, instantly. */
    transition: none !important;
}
.btn-option--select.active span,
.btn-option--select.active label,
.wishlist-button.wishlist-active:not(:where(.vw-owner-msg)) span { color: #2F6B47 !important; }
/* 43.1.3 THE PROFILE ACTION ROW'S TWO SHOWN-INTEREST STATES TAKE THE SAME POSITIVE GREEN
   (S227, backlog row 59 / S217-V1). Rob: "that 'interested' button just changes to 'message'
   doesn't it? ... with a venue or organiser, it should do the same thing and also change to
   'message' in green."
   MEASURED BEFORE on the live site as cold_prem19 at 1280 and 390: the matched pair's Message
   button on /members/cold_std22/ rendered rgb(255,255,255) on a rgb(204,153,0) border with
   rgb(3,27,131) text, while the SAME shown state on an organiser card at /organisers/ rendered
   rgb(234,244,236) / rgb(47,125,79) / rgb(47,107,71). One meaning, two looks.
   CAUSE: nothing anywhere styles .interest-btn-message or the one-way Interested state at all,
   so the row's shared white shell from profile-editor.css 16.7.5 is what shows.
   The one-way state carries NO class of its own (interest-system.php 4.1 leaves it as plain
   .interest-btn), so its title is the only hook the markup offers; that title is set the same
   way in all three code paths, the server render and both JS handlers.
   COLOURS ONLY, deliberately: 43.1.2 above also clears box-shadow and transform, which is the
   wishlist button's press metaphor. This row is a SET of three buttons sharing one shell, and
   its existing state variant (.member-fav-btn.is-fav, profile-editor.css 16.7.5) likewise
   changes colour and leaves the shape alone.
   S238 F08: the business interest control on a venue or organiser profile (interest-system.php
   4.1.1b) carries .wishlist-active in both its shown states, Interested and the Message anchor,
   and is listed here so the row's white shell and the cream .generic-button a rule do not paint
   over the same green its card shows. */
#item-buttons.profile-header-actions .interest-button-wrap > .wishlist-button.wishlist-active,
#item-buttons.profile-header-actions .interest-button-wrap > .wishlist-button.wishlist-active:hover,
#item-buttons.profile-header-actions .interest-button-wrap > a.interest-btn-message,
#item-buttons.profile-header-actions .interest-button-wrap > a.interest-btn-message:hover,
#item-buttons.profile-header-actions .interest-button-wrap > a.interest-btn[title="Click to withdraw interest"],
#item-buttons.profile-header-actions .interest-button-wrap > a.interest-btn[title="Click to withdraw interest"]:hover {
    background: #EAF4EC !important;
    border-color: #2F7D4F !important;
    color: #2F6B47 !important;
}
/* end of 43.1.3 */
/* end of 43.1 */

/* 43.2 .btn-dashboard — every button inside the dashboard / personal pages.
   !important on visual properties to defeat Seeko parent theme overrides. */
.btn-dashboard {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    align-self: center !important;
    gap: 8px !important;
    /* Asymmetric vertical padding (-1px top, +1px bottom) compensates for
       Montserrat bold caps sitting high in the em-box. Total vertical padding
       unchanged (21px); text glyph shifts up 1px without changing height. */
    padding: 10px 24px 11px !important;
    border-radius: 10px !important;
    font-family: var(--font-heading) !important;
    font-weight: 700 !important;
    font-size: 14px !important;
    line-height: 1 !important;
    letter-spacing: normal !important;
    background: var(--color-cream) !important;
    color: var(--color-navy) !important;
    border: 2px solid var(--color-gold) !important;
    box-shadow: var(--shadow-gold-hover) !important;
    cursor: pointer !important;
    text-decoration: none !important;
    text-transform: none !important;
    white-space: nowrap !important;
    margin: 0 !important;
    transition: background-color 120ms ease-out, box-shadow 120ms ease-out, transform 120ms ease-out !important;
}
.btn-dashboard:hover {
    background: var(--color-cream-hover) !important;
    color: var(--color-navy) !important;
    border-color: var(--color-gold) !important;
    /* S245 row 130: the one shadow (see 43.1). The navy two-layer lift that stood here was the BRAND_GUIDE 9.1 pair of May 2026, which D-655 (black, not gold or navy) and the
       dashboard buttons Rob signed off (hovered shadow = rest shadow, measured) both superseded: the Report button on an event or a profile showed a navy shadow of a different
       size and colour from the Show Interest or Block button beside it. */
    box-shadow: var(--shadow-gold-hover) !important;
    transform: translateY(-1px) !important;
    text-decoration: none !important;
}
/* S245 row 130, the pressed state (D-640): the darker cream (already this button's hover ground), no shadow, no lift. Nothing stated it, so a held Report or Cancel RSVP painted
   its hover. After the hover rule at the same specificity. */
.btn-dashboard:active:where(:not(:disabled):not(.is-disabled)) {
    background: var(--color-cream-hover) !important;
    color: var(--color-navy) !important;
    border-color: var(--color-gold) !important;
    box-shadow: none !important;
    transform: none !important;
}
.btn-dashboard:disabled,
.btn-dashboard.is-disabled {
    opacity: 1 !important;
    box-shadow: none !important;
    cursor: not-allowed !important;
    transform: none !important;
}
/* end of 43.2 */

/* 43.3 .btn-menu — dashboard sub-section navigation tab.
   !important on visual properties to defeat Seeko parent theme overrides. */
.btn-menu {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    align-self: center !important;
    padding: 7px 17px !important;
    border-radius: 10px !important;
    font-family: var(--font-heading) !important;
    font-weight: 700 !important;
    font-size: 13px !important;
    line-height: 1 !important;
    letter-spacing: 0.02em !important;
    background: transparent !important;
    color: var(--color-navy) !important;
    border: 1px solid var(--color-gold) !important;
    box-shadow: var(--shadow-gold-hover) !important;
    cursor: pointer !important;
    text-decoration: none !important;
    text-transform: none !important;
    white-space: nowrap !important;
    margin: 0 !important;
    transition: background-color 120ms ease-out, box-shadow 120ms ease-out, transform 120ms ease-out, border-color 120ms ease-out, color 120ms ease-out !important;
}
.btn-menu:hover:not(.btn-menu--active) {
    background: var(--color-cream) !important;
    color: var(--color-navy) !important;
    border-color: var(--color-gold) !important;
    /* S245 row 130: the one shadow (see 43.1 and 43.2). */
    box-shadow: var(--shadow-gold-hover) !important;
    transform: translateY(-1px) !important;
    text-decoration: none !important;
}
/* S245 row 130, the pressed state (D-640): the darker cream, no shadow, no lift; the active tab (.btn-menu--active, below) is its own state and is left out. The hover rule above
   counts 0,3,0 (its :not(.btn-menu--active) counts), so this one is written with the same :not() and a second guard to count 0,4,0 and win while both match. */
.btn-menu:active:not(.btn-menu--active):not(:disabled) {
    background: var(--color-cream-hover) !important;
    color: var(--color-navy) !important;
    border-color: var(--color-gold) !important;
    box-shadow: none !important;
    transform: none !important;
}
/* Active state — gold-filled, navy text, flush (no shadow = pressed-in / selected) */
.btn-menu--active,
.btn-menu--active:hover,
.btn-menu--active:focus {
    /* S207 05/09/26, Rob item A4: hover fills with the DARKER cream, not gold. */
    background: var(--color-cream-hover, #FFF5CC) !important;
    color: var(--color-navy) !important;
    border-color: var(--color-gold) !important;
    box-shadow: none !important;
    transform: none !important;
    cursor: default !important;
}
/* end of 43.3 */

/* 43.4 TWO BUTTONS WHOSE OWN CSS IS WRITTEN BY PHP, TAKING THE SITE'S STATES (S244, Rob, the 8th of October 2026). The branded dialog's buttons (mu-plugins/uksocials-dialog.php 1.1,
   injected into <head> at the moment a dialog first opens) and the Spotify note's Got it (mu-plugins/profile-system.php 2.15, an inline <style> in wp_footer) are styled by
   rules in files that are not this one, and both are injected AFTER this sheet, so a rule here wins only on specificity, never on order. Every selector below is therefore
   deeper than the rule it replaces (named in each comment) and deeper than Seeko's (0,1,1) `button:hover` and (0,3,1) `button:not([disabled]):not(.disabled):active`, which set
   color, background-color and border-color: all three are stated in every state. The values are not new. They are the canonical button's: the hover lift of .btn-option
   (43.1, translateY(-1px), 120ms) and the ONE shadow, --shadow-gold-hover (S245 row 130 replaced the two-layer lift shadow these rules first took from .btn-option, which the
   signed-off dashboard buttons do not have), the light-to-darker cream pairing the site's cream buttons use
   (--color-cream, --color-cream-hover), the red variant's own colours (.btn--danger, 42.8: the 12 percent wash, --color-error), and the pressed look D-640 sets (darker cream,
   no shadow). Where the PHP-owned rules can later be deleted, these keep working untouched. */

/* 43.4.1 The branded dialog (uksDialog.confirm / .notice): the Delete for good, Empty bin, cancel-your-place, leave-the-editor and every other dialog button on the site.
   Row 114 (Rob: "This pop up when deleting, neither button has the correct hover styling. ... They're all supposed to be the same") and row 124 (the cancel-your-place dialog:
   "the styling on hover for both buttons is completely wrong"). MEASURED LIVE with a real pointer on both dialogs, both buttons: hover painted the dialog's own cream (or its
   pale red) and Seeko's `button:hover` took the ring away (border-color rgba(0,0,0,0): the gold ring on Keep it and Keep my place, the red ring on Delete for good and Yes, cancel),
   with no lift and no shadow change; pressed painted Seeko's grey #eee with a #191919 label and no ring (the dialog's own :active rule, background #FFFBE6, lost to Seeko's
   (0,3,1)). The dialog's rest ground is untouched (white, the ring, the label: D-592 and D-640 both leave the branded dialog its own; its rest shadow is the next paragraph's). The premium intro
   popup borrows these class names with its own rules (profile-editor.css .uks-std-intro) and is excluded here. */
/* S245 row 130 (Rob, the 9th of October 2026, on Keep it against Delete for good and Keep my place against Yes, cancel: "the drop shadow looks much better on that button as opposed to the
   delete for good button", "the yes cancel drop shadow does not match ... The positive ones are much bigger than the negative ones. So you need to check which ones actually correct and
   make sure they all have them"). THE ONE SHADOW, and both buttons of the pair carry it from rest. MEASURED live with a real pointer on both dialogs: the dialog's own rest shadow is the
   small navy pair the plugin writes (0 2px 0 + 0 3px 6px rgba(3,27,131,.10), mu-plugins/uksocials-dialog.php 1.1), on BOTH buttons, and the hover I wrote in S244 gave only the hovered one
   the two-layer lift shadow, so a hovered Keep it sat beside a resting Delete for good with a shadow several times the size. READ OFF the signed-off dashboard buttons as a member (Prev
   and Next, Randomise, Profile and Customise, the calendar arrows; the same as the Messages .btn--primary and .btn--danger Rob passed), the shadow is `0 4px 12px rgba(0,0,0,.16)`
   (--shadow-gold-hover, D-640 and D-655) at rest AND hovered, and none when held. Both buttons now carry it at rest (this rule outranks the plugin's 0,1,0 on specificity: 0,3,0) and keep
   it when hovered, so the pair always matches; the lift stays, and the held state below is untouched. Where the plugin's own CSS is later cleaned up this keeps working. */
.uks-dialog-overlay:not(.uks-std-intro) .uks-dialog-btn {
    box-shadow: var(--shadow-gold-hover);
    transition: background-color 120ms ease-out, box-shadow 120ms ease-out, transform 120ms ease-out;
}
.uks-dialog-overlay:not(.uks-std-intro) .uks-dialog-btn:hover {
    background: var(--color-cream);
    border-color: var(--color-gold);
    color: var(--color-navy);
    box-shadow: var(--shadow-gold-hover);
    transform: translateY(-1px);
}
.uks-dialog-overlay:not(.uks-std-intro) .uks-dialog-btn--danger:hover {
    background: rgba(196, 28, 28, 0.12);
    border-color: var(--color-error);
    color: var(--color-error);
}
.uks-dialog-overlay:not(.uks-std-intro) .uks-dialog-btn:not([disabled]):not(.disabled):active {
    background: var(--color-cream-hover);
    border-color: var(--color-gold);
    color: var(--color-navy);
    box-shadow: none;
    transform: translateY(1px);
}
.uks-dialog-overlay:not(.uks-std-intro) .uks-dialog-btn--danger:not([disabled]):not(.disabled):active {
    background: rgba(196, 28, 28, 0.12);
    border-color: var(--color-error);
    color: var(--color-error);
}

/* 43.4.2 The Spotify note's Got it (the Customise page). Row 97 (Rob: "the hover action on the got it button on the Spotify warning on the customise page. That's wrong. It should
   be light cream to dark cream on hover, the same pop effect that the other buttons have"). MEASURED LIVE with a real pointer on example_amelia_rowe's Customise page: rest the
   light cream (#FFFBE6) with the gold ring; hover painted solid gold (rgb(204,153,0), the inline rule .spotify-info-popup-dismiss:hover, profile-system.php 2.15) with the ring gone
   (Seeko's border-color transparent) and no lift; pressed Seeko's grey #eee with a #191919 label. It now goes from the light cream to the darker cream (--color-cream-hover) with
   the ring kept, the navy label, and the canonical lift and shadow; pressed is the darker cream with no shadow. Its pill shape and size are left as they were.
   S245 row 130: the shadow is the ONE shadow (--shadow-gold-hover, as the dashboard buttons Rob signed off carry it, at rest and hovered). It had none at rest and the two-layer lift
   shadow hovered, so it appeared from nothing at several times the size of every other button's; it now carries the one shadow at rest and keeps it when hovered. */
/* S245 B8, the label's ink (Rob's rule: a label is centred by the ink of its capitals, not by its box). MEASURED with the accepted overlay (tools/s238_btn_label_overlay.py, clean 8x pictures of
   the button on example_amelia_rowe's Customise page): the capital band of "Got it" sat 0.82px ABOVE the button's centre at 1280 (11.05px above the capital, 12.68px below the baseline) and
   1.32px above at 360 (10.99 above, 13.62 below), against the 0.5px tolerance. The PHP rule this sits over (profile-system.php 2.15) pads 6px above and 6px below. Moving the 12px total
   to 7px above and 5px below keeps the button's height exactly as it was and moves the painted label down one whole pixel (padding moves text in whole pixels only, LB-402),
   which then reads 0.18px BELOW the button's centre at 1280 and 0.32px ABOVE it at 360 (same tool, patched copy served in place of the live sheet), both inside the 0.5px tolerance. */
.spotify-info-popup .spotify-info-popup-dismiss {
    padding: 7px 18px 5px;
    box-shadow: var(--shadow-gold-hover);
    transition: background-color 120ms ease-out, box-shadow 120ms ease-out, transform 120ms ease-out;
}
.spotify-info-popup .spotify-info-popup-dismiss:hover {
    background: var(--color-cream-hover);
    border-color: var(--color-gold);
    color: var(--color-navy);
    box-shadow: var(--shadow-gold-hover);
    transform: translateY(-1px);
}
.spotify-info-popup .spotify-info-popup-dismiss:not([disabled]):not(.disabled):active {
    background: var(--color-cream-hover);
    border-color: var(--color-gold);
    color: var(--color-navy);
    box-shadow: none;
    transform: none;
}
/* 43.4.3 THE WIDGET DROP-DOWNS' OPTIONS, EACH ITS OWN BORDERED ROW (S245 rows 45 and 87; D-820). Rob, the 7th of October 2026: "the political party widget drop down isn't correctly sectioned off,
   they should all just be on their own little panels with borders and things" (row 45) and "options must be isolated like the Show Interest drop-down (each its own bordered row, cream when
   chosen); the party drop-down is bland and unisolated" (row 87). The reference is the Show Interest drop-down (mu-plugins/interest-system.php 7.1.3, `.interest-reason-option`): 2px solid #CC9900,
   radius 12px, a white row, cream (#FFFBE6) when hovered, border and background easing over .15s, 8px between rows. The rail drop-downs built on `.sigil-chooser-entry` (venue, organiser,
   political party, social links, interest pills) have their row CSS written by PHP (mu-plugins/profile-system.php, an inline <style> in wp_footer, after this sheet), so every selector here is one
   class deeper than the rule it overrides (0,2,0 and up against 0,1,0 to 0,3,0) and replaces nothing in this file. The Wish List's `.wl-row` rows already sit inside bordered section panels and
   batch C row 98 holds their geometry, so they are left. MEASURED LIVE on example_aaron_fitzgerald's Customise page at 1280: the rows had no border and a transparent ground (the cream wash was the
   only thing marking the placed or voted row), 48px high with no gap. THE ONE DEPARTURE FROM THE SHOW INTEREST VALUES IS THE GAP AND THE ROW PADDING: the party drop-down carries eight rows and
   the popup's own cap is min(70vh, 520px) (mu-plugins/profile-system.php 0.1.4f). With 8px gaps and the row's 8px padding the popup was 582px and grew a scroll bar (measured, 520px visible);
   with 6px gaps and 4px row padding it is 508px and does not. Chosen (placed or voted) and hovered rows are cream, as the Show Interest row is on hover; the party rows are not click targets (their
   Vote and Place buttons are), so they keep the default cursor, but they take the cream wash on hover too, as D-820 asks. */
.sigil-chooser-popup .sigil-chooser-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.sigil-chooser-popup .sigil-chooser-entry {
    padding: 4px 10px;
    background: #FFFFFF;
    border: 2px solid var(--color-gold);
    border-radius: 12px;
    transition: border-color .15s ease, background .15s ease;
}
.sigil-chooser-popup .sigil-chooser-entry:hover,
.sigil-chooser-popup .sigil-chooser-entry.is-placed,
.sigil-chooser-popup.sigil-chooser-popup--party .sigil-chooser-entry:hover,
.sigil-chooser-popup.sigil-chooser-popup--party .sigil-chooser-entry.is-voted {
    background: var(--color-cream);
}
/* The Social links drop-down's rows are form rows (the name, the web address field, the switch), not options, and mu-plugins/pickable-buttons.php 6.1.23 and 6.1.24 set their padding and ground
   with !important (a transparent ground, and a faint navy outline on hover: Rob, S79, "cream hover was horrible (cream-on-cream invisible)", because the field inside is cream). That stands:
   those rows take the gold ring from the rule above and only their 8px corner is brought to the same 12px as every other row here. */
.sigil-chooser-popup.pickable-popup.pickable-popup-social .sigil-chooser-entry-social {
    border-radius: 12px;
}
/* end of 43.4 */
/* end of 43 */

/* =============================================================================
   44. MESSAGES PAGE - ported verbatim from design_handoff_messages/design/messages.css
   (handoff 2026-06-01). Tokens live in design-tokens.css; .app/.workspace/.section-nav
   and the vp container root (#item-body) already live from the account port (B442).
   Design is authoritative - do not edit values.
   ============================================================================= */
/* =========================================================================
   UKSocials.Club — Messages page styles
   Builds on styles.css tokens (navy/gold, gold-bordered cards, radii,
   shadows). Two-panel split that mirrors the account card system.
   ========================================================================= */

/* --- small circular sigil (member avatar placeholder) ------------------ */
.sigil-sm {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  flex-shrink: 0;
  display: grid;
  place-items: center;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.02em;
  border: 2px solid var(--color-gold);
  color: var(--color-cream);
  background: linear-gradient(135deg, #2a3556, #1f2848);
  box-shadow: 0 2px 6px rgba(3, 27, 131, 0.18);
}
.sigil-sm--navy { background: linear-gradient(135deg, var(--color-navy), var(--color-navy-light)); }
.sigil-sm--org  { background: linear-gradient(135deg, var(--color-navy), var(--color-cyan)); color: var(--color-navy); }
.sigil-sm--gold { background: linear-gradient(135deg, var(--color-gold), var(--color-gold-light)); color: var(--color-navy); }

/* =========================================================================
   SPLIT SHELL — thread list (left) + conversation (right)
   Fixed-height shell; each panel scrolls internally.
   ========================================================================= */
.msg-split {
  display: flex;
  align-items: stretch;
  gap: 0;
  height: 512px;
  max-width: 1000px;
  margin: 0 auto;
}

/* Both panels share the card look — white surface, gold border, radius. */
.msg-thread-list,
.msg-conversation {
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}
/* Thread list = user-adjustable width, persisted in --msg-list-w. Clamped so
   it never drops below 220px or climbs past 45% (conversation stays the
   majority — the body is the important panel). */
.msg-thread-list {
  flex: 0 0 auto;
  width: clamp(220px, var(--msg-list-w, 320px), 45%);
  min-width: 0;
  /* R3-19 (Rob, 24/09/2026): "the entire messaging folder panel should remain fixed at all times,
     regardless of how many messages there are or what folder it is" (first ruled in round 2, item 23).
     Side by side, the shell's stretch already held this panel at the shell's 512px. Stacked on a
     phone (the column layout in the 600px block at the end of this section) its flex-basis fell back
     to its own content, so a short or empty folder shrank it. 100% of the shell holds it at the
     shell's fixed height at every width, in every folder, and the thread list scrolls inside it. */
  height: 100%;
}
.msg-conversation {
  flex: 1 1 auto;
  min-width: 0;
}

/* Drag handle sitting in the 16px gutter between the two panels.
   S244 row 119 (Rob, the 8th of October 2026: the canonical button states, "they should all follow them"): the handle is a <button>, and Seeko's `button:hover` (0,1,1)
   and `button:not([disabled]):not(.disabled):active` (0,3,1) paint its whole 16px by 494px gutter solid grey (#F0F0F0 on hover, #EEEEEE held: measured live with a real
   pointer, 1280) over this rule's `background: transparent` (0,1,0). Its states are listed here so the gutter stays clear in every one; only the 4px indicator inside
   it (below) changes, to gold, as it always did. */
.msg-resizer,
.msg-resizer:hover,
.msg-resizer:not([disabled]):not(.disabled):active {
  flex: 0 0 auto;
  width: 16px;
  align-self: stretch;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: col-resize;
  touch-action: none;
  background: transparent;
  border: 0;
  padding: 0;
}
.msg-resizer::before {
  content: "";
  width: 4px;
  height: 46px;
  border-radius: var(--radius-pill);
  background: var(--color-border-strong);
  transition: background var(--duration-fast) var(--ease-out),
              height var(--duration-fast) var(--ease-out);
}
.msg-resizer:hover::before,
.msg-resizer.is-dragging::before {
  background: var(--color-gold);
  height: 76px;
}

/* =========================================================================
   THREAD LIST PANEL
   ========================================================================= */
.msg-thread-list__head {
  padding: 16px 16px 14px;
  border-bottom: 1px solid var(--color-gold); /* S211 07/09/26 Rob: the header line is gold, not grey */
  display: flex;
  flex-direction: column;
  gap: 14px; /* S211 07/09/26 Rob: "reduce the gap between the side panel title and the search field by like 20%", for every folder; was 18px, the 01/06/26 note below stands as history. */ /* was:8px; /* Gap (Inbox text -> search top) = ~2x gap (search bottom -> grey line). Rob 2:1, 01/06/26; was var(--sp-md) */
  flex-shrink: 0;
}
.msg-thread-list__title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-md);
}
.workspace .msg-thread-list__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 20px;
  color: var(--color-navy);
  letter-spacing: -0.01em;
  margin: 0; /* kill Seeko global h2 margin-bottom (theme deviation, was 27px) */
}
/* S213 (Rob 08/09/26): the .msg-compose-btn block and its hover were DELETED. No element
   with that class exists in the messages workspace - Compose renders as a
   .section-nav__item - so the rules painted nothing. Trimming bloat, on his word. */

.msg-search {
  display: flex;
  align-items: center;
  gap: var(--sp-sm);
  padding: 0 var(--sp-md);
  height: 38px;
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-pill);
  color: var(--color-text-muted);
  background: var(--color-surface);
  transition: box-shadow var(--duration-fast) var(--ease-out);
}
html[data-nav="kbd"] .msg-search:focus-within { box-shadow: 0 0 0 2px rgba(204, 153, 0, 0.25); }
/* scope-bumped to .workspace (0,2,0) to defeat Seeko theme-static.min.css
   `input[type=search],...` (0,1,1) which forces padding .5rem 1rem + 1px grey
   border onto the design's borderless search input. padding:0 added because the
   spec relied on a clean input baseline the live theme doesn't provide. */
.workspace .msg-search__input {
  flex: 1;
  min-width: 0;
  margin: 0;          /* defeat Seeko's input margin-bottom:1rem which, under
                         .msg-search align-items:center, shoves the placeholder 8px high */
  padding: 0 23px 0 0; /* S219: the right side matches the magnifier and its gap, so the text centres on the whole box */
  border: 0;
  outline: 0;
  background: transparent;
  font: 400 14px var(--font-body);
  color: var(--color-navy);
  text-align: center; /* S219 (Rob 10/09/26): all normal text centred */
}
/* S213 item 49: the per-field rule that lived here is GONE. Item 50 solves it for the whole
   platform in one place - see PLACEHOLDER COLOUR near the top of the file. */

.workspace .msg-markread {
  align-self: flex-start;
  margin: 0; /* kill Seeko global button margin-bottom (was 16px; inflated the title row + offset Mark-all-read) */
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  white-space: nowrap;
  border: 0;
  background: transparent;
  color: var(--color-navy);
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.02em;
  padding: 2px 4px;
  border-radius: 10px;
  transform: translateY(1px);
  /* S244 rows 112 and 119: the fill, the lift and its shadow move together at the platform's button speed (.btn's, 42.8) instead of Seeko's 0.4s transform. */
  transition: background-color var(--duration-fast) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out);
}
.msg-markread svg { flex-shrink: 0; }
/* S213 item 36: this hover filled with the warm grey --color-surface-raised. Mark all read and
   Empty bin are named on Rob's hover list and take the darker cream like the rest. */
.msg-markread:hover { background: var(--color-cream-hover); }
/* S213 item 48 (Rob 08/09/26: "the tick should be green"). The tick was navy like its label.
   It now takes the platform's success green, the same one the admin attention tick uses.
   Scoped away from Empty bin, whose trash glyph stays on the error colour. */
.msg-markread:not(.msg-markread--danger) svg { color: var(--color-success); }
/* S213 item 48, second pass (Rob 08/09/26: "move the tick so it's vertically centred with the
   text"). align-items centres the glyph's BOX on the label's LINE BOX, and a line box is
   taller than the ink inside it, so the tick measured 0.750px BELOW the label's ink midline
   at 6x. Raised by exactly that. */
.msg-markread svg { transform: translateY(-0.75px); }
/* S211 T-S211-021: Empty bin, the Bin folder's own header action. Same slot, shape and
   type as Mark all read; the danger colour of the conversation delete icon. */
.workspace .msg-markread--danger { color: var(--color-error); }
.msg-markread--danger:hover { background: var(--color-error-bg); }
/* S244 rows 112 and 119 (Rob, the 8th of October 2026: "all the buttons that do something negative like delete or report, they don't have the full animation, they
   don't pop when you hover", and "the canonical button styles ... they should all follow them"). Mark all read and Empty bin took the darker cream (red wash) on
   hover and nothing else, and a press fell to Seeko's `button:not([disabled]):not(.disabled):active` (0,3,1), grey #eee with a black label, measured live with the
   pointer held down on each. They now take the site's three states: hover = the fill above and the lift (this button rests 1px low, so the lift is back to 0) with the
   .btn--primary shadow, a real pointer only and not while held; pressed = the darker cream (the 12 percent red wash on Empty bin), the label's own colour, no shadow,
   at rest height. Seeko's rule sets color, background-color and border-color; the pressed rules restate the first two (this button has no border). */
@media (hover: hover) {
.workspace .msg-markread:hover:not(:active) { transform: translateY(0); box-shadow: var(--shadow-gold-hover); }
}
.workspace .msg-markread:not([disabled]):not(.disabled):active { background: var(--color-cream-hover); color: var(--color-navy); box-shadow: none; }
.workspace .msg-markread--danger:not([disabled]):not(.disabled):active { background: rgba(196, 28, 28, 0.12); color: var(--color-error); }

/* scrollable thread list */
.msg-thread-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  /* S229 16/09/26: reverted to the values that were live before S227. Rob: "the live version
     of the messaging system is all spot on and doesn't need changing now... just scrap it." */
  padding: 14px 8px 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  scrollbar-width: thin;
}

/* --- thread row --- */
.thread {
  display: flex;
  align-items: center;
  gap: var(--sp-md);
  width: 100%;

  /* S229: the S227 margin reset removed with the rest of that change on Rob's word. */
  text-align: left;
  padding: var(--sp-md);
  border: 1px solid transparent;
  border-radius: 12px;
  background: transparent;
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out);
}
/* S244 rows 109 and 110 (Rob, the 8th of October 2026: "on hover the background of the message being hovered over is a kinda grey color again. That's not the correct
   styling for hover" and "I just hovered that second message and then clicked it and look at the styling again it's incorrect, it's got no gold border or anything ... the
   hover and click styling and animation of all those messages for every folder in that side panel all needs to be checked and corrected"). One set of states for every real
   row in every folder (Inbox, Starred, Sent, Notices, Archive, Spam, Bin share this markup):
     rest               clear, with a clear 1px border (kept, so no state moves the row by a pixel)
     hover              the light cream and the gold border: the site's list-row hover, as .ev-dd__opt:hover, .st-dd__opt:hover, .ev-timecol__opt:hover and .reg-dd__opt:hover
                        (light cream and gold border) and .event-row:hover (light cream) do it
     pressed (:active)  the darker cream (--color-cream-hover, the site's light-to-darker pair) and the gold border
     open (--active)    the light cream and the gold border, as it was (the Inbox's own open row, which Rob's pictures show without complaint);
                        open and hovered, or open and pressed: the darker cream and the gold border
   WHY THE OLD RULES FAILED, read off the live page with CDP matched styles: a row is a <button>, and Seeko's `button:hover` (seeko-dynamic.css, specificity 0,1,1) sets
   color #191919, background-color #f0f0f0 and border-color transparent, while Seeko's `button:not([disabled]):not(.disabled):active` (0,3,1) sets background-color #eee
   and border-color transparent. The old hover rule named a background only, and a warm grey one (--color-surface-raised), so on the open row the gold border lost to Seeko's
   transparent one the moment the pointer was over it (Rob's picture: the darker cream with no border), and a press flashed #eee with no border. Every state below names both
   properties of Seeko's that paint (background-color and border-color; the row's own colour paints nothing, no child inherits it), the hover rules are (0,2,1) against Seeko's
   (0,1,1), and the pressed rule carries Seeko's own :not() shape (0,4,1) so it outranks it. `button.thread` keeps the states off .thread--removed (the Undo placeholder, a div,
   which is not a row you can open). The row's own 0.15s fade of background and border (its transition) is the animation and is unchanged.
   S244 item 20 (Astra, results/s244-astra/item20-styling-note.md): the row is becoming div.thread[role="button"][tabindex="0"] so the member's name and sigil can be real links, so each
   state rule below carries a `.thread[role="button"]` alternative with its declarations unchanged (the same rule, one selector longer; nothing stacked). A div has no Seeko button rule
   to defeat; the alternatives keep the same relative weights as the button ones (hover and open-hover 0,3,0 in source order, pressed 0,5,0), so the pressed row still outranks the
   hover and the open row exactly as on the button. The Undo placeholder (.thread--removed) carries no role, so it stays out of every state. Keyboard focus is already covered by
   section 48.1 (`[role="button"]:focus-visible`).
   WHAT A DIV LACKS THAT THE BUTTON GETS FOR FREE (read off the live page by swapping a real row for a div copy and diffing every computed property; the rows then differed by 18px
   of pitch): three things come from the parent theme and the browser's own button, not from this file, so the div states them itself, each with its source:
     margin-bottom 1rem     seeko-dynamic.css `.btn, input[type=submit], ..., button { margin-bottom: 1rem }` (18px). The S229 note on .thread above is why this is kept: the row pitch stays 90px
     white-space nowrap     the browser's own button style (computed text-wrap-mode nowrap), inherited by every child of the row; a div would otherwise let a child wrap
     user-select none       the browser's own button style; a div would let a double-click highlight the words of the row
   Nothing else differs that paints (the row's own colour, #191919 on the button, paints nothing: every child that has text sets its own colour). */
.thread[role="button"] {
  margin-bottom: 1rem;
  white-space: nowrap;
  -webkit-user-select: none;
  user-select: none;
}
button.thread:hover,
.thread[role="button"]:hover { background: var(--color-cream); border-color: var(--color-gold); }
.thread--active {
  background: var(--color-cream);
  border-color: var(--color-gold);
}
button.thread--active:hover,
.thread--active[role="button"]:hover { background: var(--color-cream-hover); border-color: var(--color-gold); }
button.thread:not([disabled]):not(.disabled):active,
.thread[role="button"]:not([disabled]):not(.disabled):active { background: var(--color-cream-hover); border-color: var(--color-gold); }

.thread__main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.thread__top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-sm);
}
.thread__name {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 14px;
  color: var(--color-navy);
  min-width: 0;
}
.thread__name-text {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.thread--unread .thread__name { font-weight: 700; }
.thread__tag {
  flex-shrink: 0;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 2px 6px 3px;
  border-radius: var(--radius-pill);
  background: rgba(3, 27, 131, 0.07);
  color: var(--color-navy);
  border: 1px solid transparent;
}
.thread__tag--group { background: rgba(0, 204, 255, 0.12); color: #0a5a78; }
.thread__tag--system { background: rgba(204, 153, 0, 0.12); color: var(--color-gold-dark); }
.thread__tag--offer { background: rgba(204, 153, 0, 0.16); color: var(--color-gold-dark); }
.thread__tag--notice { background: rgba(3, 27, 131, 0.10); color: var(--color-navy); }
.thread__time {
  flex-shrink: 0;
  font-size: 11px;
  font-weight: 600;
  color: var(--color-text-muted);
  font-family: var(--font-heading);
  /* S244 row 115: a whole, ODD line (17px, was the inherited 1.6 = 17.6px) so the time's box has an integral baseline and the capital band lands on the same
     pixel row wherever the row sits on the page (measured at five sub-pixel phases: 17.6px gave -0.437 on four and -1.437 on one, 17px gives -0.437 on all five;
     an even 18px gave +0.563 on three and -0.437 on two), da.md 21b. See .thread__flags below. */
  line-height: 17px;
  /* S245 row 137 (Rob, the 9th of October 2026, on the picture of the Inbox row's time: "add another 2 pixels to the padding between the number and the word month. They're
     just a little too close at the moment."). The time is ONE text node, the server's own "1 month", "3 weeks" or "4 hours": a number, ONE space, the unit word. So the gap Rob
     means is that single space, and the only stylesheet lever on it is word-spacing, which adds its value to every space in the text: 2px added to the one space is the two pixels
     he asked for, on every row of every folder alike. Measured on the live page at 1280 with the row in its unread state (the picture Rob commented on): the gap between the
     painted digit and the painted m, read from the pixels at 8x, goes from 5.04px to 7.04px (5.18px to 7.18px on a read row), the time's box from 42.78px to 44.78px, and
     nothing else about it moves (the markup is untouched, its line, its colour and its place on the dot's row are the S244 row 115 values above). */
  word-spacing: 2px;
}
.thread--unread .thread__time { color: var(--color-gold-dark); }
.thread__preview {
  font-size: 13px;
  color: var(--color-navy); /* S207 05/09/26 (visual item 11): the preview line read black beside navy names; Rob: "black not blue" */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.4;
}
.thread--unread .thread__preview { color: var(--color-navy); font-weight: 600; }

/* S244 row 115 (Rob 08/10 ~18:1x: "The time a message arrived, currently in gold, is too high. It should be exactly centered on the same row as the little gold
   indicator button."). The time moved into this box (messages-app.js threadRow, Astra's item 25), but this rule stacked its children in a column, so the time sat ABOVE the
   dot: MEASURED on the live page by the painted pixels at 8x (the digit 1's capital band against the gold disc), the time's centre was 17.437px above the dot's centre
   (17.297px by the boxes). The box is a ROW now (the same 4px gap, the time first, then any star, then the dot), replacing the column rather than stacking on it.
   Centring is by INK (da.md section 9): with the whole 17px line above, the capital band's centre sits 0.437px above the box centre that align-items centres the dot on,
   at every phase; text cannot move by a fraction of a pixel (da.md 9a) but a filled disc can, so the dot takes translateY(-0.437px) and its centre lands on the capital
   band's centre: re-measured the same way, -0.001px at five phases and at page scale 1 and 2. */
.thread__flags {
  flex-shrink: 0;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-width: 14px;
}
.thread__dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--color-gold);
  box-shadow: 0 0 0 2px rgba(204, 153, 0, 0.2);
  transform: translateY(-0.437px);
}
.thread__star { color: var(--color-gold); display: inline-flex; }

/* removed states (deleted / spam / archived) — calm, with undo */
.thread--removed {
  display: flex;
  align-items: center;
  gap: var(--sp-sm);
  padding: var(--sp-md);
  border-radius: 12px;
  background: var(--color-surface-sunken);
  color: var(--color-text-muted);
  font-size: 13px;
}
.thread__deleted-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.thread__undo {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex-shrink: 0;
  border: 1.5px solid var(--color-gold);
  background: var(--color-cream);
  color: var(--color-navy);
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 12px;
  padding: 4px 12px;
  border-radius: var(--radius-pill);
}
.thread__undo:hover {
  background: var(--color-cream-hover, #FFF5CC);
  color: var(--color-navy, #031B83);
  border-color: var(--color-gold, #CC9900);
}

/* =========================================================================
   CONVERSATION PANEL
   ========================================================================= */
.msg-conv-head {
  display: flex;
  align-items: center;
  gap: var(--sp-md);
  padding: var(--sp-md) var(--sp-lg);
  border-bottom: 1px solid var(--color-gold); /* S211 07/09/26 Rob: the header line is gold, not grey */
  flex-shrink: 0;
}
.msg-conv-head__text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.msg-conv-head__name {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 16px;
  color: var(--color-navy);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.msg-conv-head__sub {
  font-size: 12px;
  color: var(--color-text-muted);
  font-weight: 600;
}
.msg-conv-head__actions {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 2px;
}
.msg-conv-head__action {
  flex-shrink: 0;
  width: 36px; height: 36px;
  display: grid; place-items: center;
  border: 1.5px solid var(--color-gold);
  border-radius: 50%;
  background: var(--color-cream);
  color: var(--color-navy);
  transition: all var(--duration-fast) var(--ease-out);
}
/* S213 item 44 (Rob, 08/09/26: "the borders disappear, and the cream doesn't go from light to
   dark"). Measured on the live page with a real pointer: on hover borderTopColor read
   rgba(0, 0, 0, 0). The cause is that this hover rule declared no border-color at all, so the
   resting gold (one specificity step lower) was beaten by Seeko's own button:hover, which sets
   border-color: transparent. It is declared here now. The fill goes light cream at rest to the
   darker cream on hover, the platform's own pairing (BRAND_GUIDE 9.3), instead of white to light
   cream. :active carries the same :not() shape Seeko uses so it outranks its grey
   button:not([disabled]):not(.disabled):active and a click no longer flashes #eee with no border. */
/* S244 rows 112 and 119 (Rob, the 8th of October 2026: the delete and report icons "don't pop when you hover", and the canonical button states "they should all follow
   them"). The four round icons had the fill and the border on hover and no lift, and the round Send button below is the same family (S213 item 44) but had a rule of
   its own that left the label to Seeko's `button:hover` (color #191919: the paper plane went black, measured live) and had no pressed state at all (grey #eee, a black
   plane and no ring, measured live with the pointer held). They now share ONE rule per state. Hover: the fill, the ring and the label's own colour, plus the lift
   (translateY(-1px)) and the --shadow-gold-hover shadow the Send button already took, a real pointer only and not while held (the gate .btn--primary uses). Pressed: the
   darker cream, the ring, the label, no shadow, at rest height. The red delete icon below keeps its own red fill, ring and label and inherits the lift from here.
   Seeko's rules set color, background-color and border-color (and box-shadow on :focus); all three are stated in each state. */
.msg-conv-head__action:hover,
.msg-composer__send:hover {
  background: var(--color-cream-hover);
  border-color: var(--color-gold);
  color: var(--color-navy);
}
@media (hover: hover) {
.msg-conv-head__action:hover:not(:active),
.msg-composer__send:hover:not(:active),
.msg-back:hover:not(:active) {
  transform: translateY(-1px);
  box-shadow: var(--shadow-gold-hover);
}
}
.msg-conv-head__action:not([disabled]):not(.disabled):active,
.msg-composer__send:not([disabled]):not(.disabled):active,
.msg-back:not([disabled]):not(.disabled):active {
  background: var(--color-cream-hover);
  border-color: var(--color-gold);
  color: var(--color-navy);
  box-shadow: none;
}
.msg-conv-head__action--danger { color: var(--color-error); border-color: var(--color-error); }
.msg-conv-head__action--danger:hover,
.msg-conv-head__action--danger:not([disabled]):not(.disabled):active {
  background: var(--color-cream-hover);
  border-color: var(--color-error);
  color: var(--color-error);
}
/* SVG as block kills the inline baseline gap, so grid place-items centres it true. */
.msg-conv-head__action svg,
.msg-composer__send svg { display: block; }
/* S244 row 100 (Rob, the 8th of October 2026: "the send button on the messaging is slightly off centre. It looks a little bit to the right"). The rule that stood on
   this line, `.msg-composer__send svg { transform: translate(1px, 1px); }`, is deleted, not overridden. Measured from the painted pixels at 8x against the button's own
   gold ring, it held the paper plane's ink 1.012px to the right of the ring's centre and 0.994px below it. The plane is drawn centred in its 24 unit box and the box is
   centred in the 42px button by place-items: center, so with no transform it sits on the centre. The 0.5px correction below is for the four header icons only. */
/* S213 item 47, second pass (Rob 08/09/26: "they all still look slightly left"). He was right and
   so was the pixel scan: photographed at 8x and measured against each button's own PAINTED gold
   ring, the glyph ink sat 0.500px left and 0.500px high. The viewBox centring is exact (ink centre
   11.975 of 24 on both axes), so the half pixel comes from the ring: a 1.5px border cannot land on
   a whole device pixel on every side, and the content box shifts with it. Corrected once, here,
   against a measurement - not a guess, and not inside the viewBox where it would clip. */
.msg-conv-head__action svg { transform: translate(0.5px, 0.5px); }
/* S213 items 45 and 47 (Rob 08/09/26). Two faults, one cause. The buttons rendered 38x36, so the
   "circles" were ellipses: Seeko's own `button` rule supplies width:auto and 9px 18px of padding
   and sits one specificity step above the component rule, so it was drawing the box. And the
   glyphs looked pushed left with the Archive lid clipped on its left edge only - measured, the
   lid overhung 0.65 units on the left against 2.0 on the right - because the runtime centring in
   messages-app.js shifted each glyph 1.4 units left INSIDE its own viewBox, which clips. The box
   is fixed here; the shift is removed at source in centerIcons(). */
#buddypress .workspace .msg-conv-head__action {
  width: 36px !important;
  height: 36px !important;
  padding: 0 !important;
  border-width: 1.5px !important;
}

/* back button — hidden on desktop, shown on narrow */
.msg-back {
  display: none;
  flex-shrink: 0;
  width: 36px; height: 36px;
  place-items: center;
  border: 1.5px solid var(--color-gold);
  border-radius: 9px;
  background: var(--color-surface);
  color: var(--color-navy);
  transition: all var(--duration-fast) var(--ease-out);
}
/* S244 row 119 (the canonical button's three states): the Back button on a phone had the cream fill on hover and nothing else, so Seeko's `button:hover` took the ring away
   (border-color transparent) and turned the arrow black (color #191919), and a press fell to its grey #eee (all three measured live at 360 with a real pointer). It rests
   white, so its hover fill stays the light cream it had; the ring and the label's own colour are stated here and the lift and the pressed state join the round icons' rules. */
.msg-back:hover { background: var(--color-cream); border-color: var(--color-gold); color: var(--color-navy); }
/* S244 row 119, the same rule for the rows of the Compose tab's recipient list (.msg-to-opt, whose own look is injected by messages-app.js and gives it a cream hover): held down
   it fell to Seeko's grey #eee (measured live, a real pointer held on a suggestion). It takes the darker cream, the site's pressed fill for a list row (the Inbox rows' pressed rule). */
.msg-to-opt:not([disabled]):not(.disabled):active { background: var(--color-cream-hover); }

/* message history */
/* S244 row 107 (Rob, the 8th of October 2026: "the scroll bar on the right is not the correct style gold scroll bar either. That's being used on for example the date
   scroller picker drop down thing on the create event page"). The conversation pane takes the Create Event dropdown's gold scrollbar value for value from .ev-dd__menu
   (page-polish.css 21494 to 21501, S227): 12px wide, a white pill track with a 1.5px #E0C56A border, a #DDB94B pill thumb, and the two gold chevron buttons. This rule used
   to set `scrollbar-width: thin`, and in Chrome that property switches every ::-webkit-scrollbar rule OFF for the element, so a gold scrollbar written beside it
   would have shown nothing: the line is taken out of the rule here (replaced, not overridden). The thread list's scrollbar (.msg-thread-scroll, which also sets
   `scrollbar-width: thin`) is not part of this row and is unchanged. */
.msg-conv-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--sp-lg);
  display: flex;
  flex-direction: column;
  gap: var(--sp-sm);
  background:
    linear-gradient(0deg, rgba(3,27,131,0.015), rgba(3,27,131,0.015)),
    var(--color-surface);
}
.msg-conv-scroll::-webkit-scrollbar { width: 12px; }
.msg-conv-scroll::-webkit-scrollbar-track { background: #ffffff; border: 1.5px solid #E0C56A; border-radius: var(--radius-pill); margin: 2px 0; }
.msg-conv-scroll::-webkit-scrollbar-thumb { background: #DDB94B; border-radius: var(--radius-pill); border: 3px solid transparent; background-clip: content-box; }
.msg-conv-scroll::-webkit-scrollbar-button { display: block; height: 13px; background: #ffffff no-repeat center; background-size: 9px 9px; }
.msg-conv-scroll::-webkit-scrollbar-button:vertical:decrement { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23CC9900' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 15l6-6 6 6'/%3E%3C/svg%3E"); }
.msg-conv-scroll::-webkit-scrollbar-button:vertical:increment { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23CC9900' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); }
.msg-conv-scroll::-webkit-scrollbar-button:vertical:start:increment,
.msg-conv-scroll::-webkit-scrollbar-button:vertical:end:decrement { display: none; }
/* S244 row 108 (Rob, the 8th of October 2026: "there's a great pill here - the one that has the date and time at the top of the conversation window? Why is that colour?
   And the label is lower than centre?"). COLOUR: the site's status pill, copied from .att-chip--reserved (the Attendance Reserved pill): --color-cream ground, --color-navy
   label, gold border (1px here: that rule's 1.5px paints as 1px at 100%, and 1px keeps the box on whole pixels). The old ground was the warm grey --color-surface-sunken
   under a 55% navy label: grey is not a site colour on a member surface. LABEL, measured from the painted pixels at 8x as the middle of the label's capital band
   against the middle of the pill: it sat 0.56px ABOVE the pill's centre in every position of the page (Rob's own picture, messages-06: pill rows 71 to 94, label rows 79 to
   85, eight rows above and nine below). Padding is now 5px above and 4px below the 16px line, so with the 1px borders the pill is 27px tall: an ODD height, whose centre is a
   pixel's centre, and the label's baseline is a whole number of pixels (1 + 5 + 11) below the pill's top, so the label and the pill round together wherever the pill falls
   on the screen. Result in the same measurement: 0.06px above the centre, at 1280 and 360, at every fraction of a pixel from 0 to 0.875. */
.msg-conv-date {
  align-self: center;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-navy);
  background: var(--color-cream);
  border: 1px solid var(--color-gold);
  padding: 5px 12px 4px;
  border-radius: var(--radius-pill);
  margin-bottom: var(--sp-xs);
}

.bubble-row {
  display: flex;
  flex-direction: column;
  max-width: 76%;
}
.bubble-row--in  { align-self: flex-start; align-items: flex-start; }
.bubble-row--out { align-self: flex-end; align-items: flex-end; }
.bubble__who {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 11px;
  color: var(--color-gold-dark);
  margin: var(--sp-xs) 0 2px var(--sp-md);
}

.bubble {
  display: inline-flex;
  align-items: flex-end;
  gap: var(--sp-sm);
  padding: 9px 14px 8px;
  font-size: 14px;
  line-height: 1.45;
  border-radius: 16px;
  border: 1.5px solid transparent;
  text-wrap: pretty;
}
.bubble--in {
  background: var(--color-surface);
  border-color: var(--color-navy);
  color: var(--color-navy);
  border-bottom-left-radius: 5px;
}
.bubble--out {
  background: var(--color-cream);
  color: var(--color-navy);
  border-color: var(--color-gold);
  border-bottom-right-radius: 5px;
}
.bubble__text { min-width: 0; }
/* Links inside a message bubble (S132; RESHAPED S202, Rob 02/09/26). Only Lilu's messages ever
   contain them - see escLinkify() in messages-app.js. The S132 shape was gold text that went NAVY
   on hover, and Rob caught it on the community-guidelines link in a photo warning: "it just looks
   like only other text". His ruling: the same treatment as every other button - a light-cream pill
   (D-429 tokens: --color-cream at rest, --color-cream-hover on hover), navy text throughout, gold
   hairline. No underline at rest and none appearing on hover (D-219). break-word so a long
   tokenised accept URL still wraps inside the bubble instead of blowing out its width. */
.bubble__text a {
  display: inline-block;
  max-width: 100%;
  margin: 2px 0;
  padding: 2px 10px;
  background: var(--color-cream);
  color: var(--color-navy);
  border: 1.5px solid var(--color-gold);
  border-radius: 999px;
  font-weight: 700;
  line-height: 1.5;
  text-decoration: none;
  overflow-wrap: break-word;
  word-break: break-word;
  transition: background-color 0.15s ease;
}
.bubble__text a:hover,
.bubble__text a:focus-visible {
  background: var(--color-cream-hover);
  color: var(--color-navy);
  text-decoration: none;
  outline: none;
}
.bubble__time {
  flex-shrink: 0;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
  transform: translateY(2px);
}
.bubble--in .bubble__time { color: rgba(3, 27, 131, 0.5); }
.bubble--out .bubble__time { color: var(--color-gold-dark); }

/* Flag-to-admin control on other members' group-chat posts (D-255 / D-257, added S132).
   Lives INSIDE .bubble, so it inherits that rule's existing inline-flex + align-items: flex-end
   + gap and needs no layout of its own. Muted navy at rest to match .bubble__time's weight, gold
   on hover/focus per the brand's hover-invert language. Group chats only - never on 1:1. */
.bubble__flag {
  flex-shrink: 0;
  display: grid;
  place-items: center;
  width: 18px;
  height: 18px;
  padding: 0;
  border: 0;
  background: none;
  border-radius: 50%;
  color: rgba(3, 27, 131, 0.4);
  cursor: pointer;
  transform: translateY(1px);
  transition: color var(--duration-fast) var(--ease-out), background var(--duration-fast) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out);
}
.bubble__flag svg { display: block; }
.bubble__flag:hover,
.bubble__flag:focus-visible {
  color: var(--color-gold);
  background: rgba(204, 153, 0, 0.10);
  outline: none;
}
/* S244 rows 112 and 119 (Rob, the 8th of October 2026: "report ... don't pop when you hover", and the canonical button states): the flag that reports a message had the
   gold wash and the gold glyph on hover and no lift, and a press fell to Seeko's grey #eee with a black glyph (measured live, pointer held). Hover now lifts (this control
   rests 1px low, so the lift is back to 0) with the --shadow-gold-hover shadow, a real pointer only and not while held; pressed is the darker cream with the gold glyph
   and no shadow. The flagged state (--done, aria-disabled) stays exactly as F15 made it: it does not react. */
@media (hover: hover) {
.bubble__flag:not(.bubble__flag--done):hover:not(:active) { transform: translateY(0); box-shadow: var(--shadow-gold-hover); }
}
.bubble__flag:not(.bubble__flag--done):not([disabled]):not(.disabled):active { background: var(--color-cream-hover); color: var(--color-gold); box-shadow: none; }
/* F15 (S238 26/09/2026): the flag's DONE state, a state of this component. After a member flags a post the
   icon stays gold (the colour it takes on hover, so it reads as "flagged") and stops reacting: no hover
   wash, no pointer. It replaces the word "Reported" that the shared report script used to write into this
   18px circle. The control is aria-disabled, never disabled, so no other button rule restyles it. */
.bubble__flag.bubble__flag--done,
.bubble__flag.bubble__flag--done:hover,
.bubble__flag.bubble__flag--done:focus-visible {
  color: var(--color-gold);
  background: none;
  cursor: default;
}

/* composer */
.msg-composer {
  display: flex;
  align-items: center;
  gap: var(--sp-sm);
  padding: var(--sp-md) var(--sp-lg);
  /* MSG-1 (Rob, the 29th of September 2026: the message input area has no gold top border): the panel's own border. */
  border-top: 1.5px solid var(--color-gold);
  flex-shrink: 0;
  background: var(--color-surface);
}
/* scope-bumped to .workspace (0,2,0) so the design's gold 1.5px border + padding
   win over Seeko's global input rule (0,1,1) that paints a 1px grey border. */
/* S244 rows 117 and 101 (Rob, the 8th of October 2026: "when you hover over the input field to reply to a message in an inbox, the gold border disappears.
   Nothing should happen. There shouldn't be a hover change on that input field" and "The message field as the message is sending goes grey and it shouldn't
   do shouldn't change colour"). The field has ONE look in every state, so the states share this rule's body instead of getting rules of their own. Read off
   the live page with CDP matched styles, the two changes were Seeko's: `input[type=text]:hover` (theme-static.min.css, 0,2,1) sets border-color #dadada, which
   beat this rule (0,2,0); and while a message is sending messages-app.js sets disabled on the field, and Seeko's `input[type="text"]:disabled` (seeko-dynamic.css,
   0,2,1) sets background-color #f8f8f8 (the grey Rob saw; its opacity rule is 1 and the browser's grey text and border lose to ours already). :hover and :disabled
   add a pseudo-class (0,3,0), which outranks both, and every property those two rules set is in the body below. Focus is left as it was. */
.workspace .msg-composer__input,
.workspace .msg-composer__input:hover,
.workspace .msg-composer__input:disabled {
  flex: 1;
  min-width: 0;
  margin: 0;          /* defeat Seeko's input margin-bottom:1rem (off-centre under flex centering) */
  height: 42px;
  padding: 0 var(--sp-lg);
  font: 400 14px var(--font-body);
  color: var(--color-navy);
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-pill);
  outline: none;
  transition: box-shadow var(--duration-fast) var(--ease-out);
}
.msg-composer__input::placeholder { color: rgba(3, 27, 131, 0.65); }
html[data-nav="kbd"] .msg-composer__input:focus { box-shadow: 0 0 0 2px rgba(204, 153, 0, 0.25); }
.msg-composer__send {
  flex-shrink: 0;
  /* S244 row 116 (Rob, the 8th of October 2026: "the send button is actually way too high compared to the input field"). Seeko's `button`
     rule (seeko-dynamic.css, specificity 0,0,1) sets margin-bottom: 1rem (18px) on every button, and this rule never reset it, so the button's margin box
     was 60px tall in a row whose input is 42px: with align-items: center on .msg-composer the ring sat exactly 9.000px above the input's centre, measured from
     the painted pixels at 8x (the input's own rule above has had margin: 0 for the same reason from the start). It also made the whole row 18px taller than the
     design's own 12px padding (85px against 67px). Reset here, on the rule that owns the button. */
  margin: 0;
  width: 42px; height: 42px;
  display: grid; place-items: center;
  border: 2px solid var(--color-gold);
  border-radius: 50%;
  /* S213, with item 44: the round send button is the same family as the four round action icons
     in the conversation header, so it takes the same pairing - light cream at rest, the darker
     cream on hover - instead of white to light cream, and it declares its border on hover so
     Seeko's button:hover cannot take the gold ring away. */
  background: var(--color-cream);
  color: var(--color-navy);
  transition: all var(--duration-fast) var(--ease-out);
}
/* S244 rows 112 and 119: the Send button's hover and pressed states are in the one rule it shares with the four round icons (.msg-conv-head__action, above). */

/* spam / bin notice bar — replaces the composer in those folders */
/* S244 rows 105 and 111 (Rob, the 8th of October 2026: "The little section at the bottom of the notices folder still has a weird kind of grey
   background and no gold border at the top of the section" and, on the Bin and Spam, "a weird grey background with no gold border ... That seems to
   be a common issue across the bottom section of all the folders. The label itself seems to be orange as well, which is odd. Should just be blue").
   ONE footer strip for every folder (Notices, Spam, Bin, Archive, Offers, the venue-event notice): the site's light cream (--color-cream, BRAND_GUIDE
   1.2 "Brand cream") with a gold top border and a navy label. The border is copied from the composer that stands in this strip's place in the other
   folders (.msg-composer, MSG-1, the 29th of September: 1.5px solid var(--color-gold)), so the panel closes with the same line whichever folder is open.
   REPLACED, not overridden: the strip was the warm grey --color-surface-raised over the near-invisible --color-border, and the label was
   --color-text-secondary with three per-folder colour rules under it (Spam orange --color-warning, Bin the muted navy --color-text-muted, Offers
   --color-gold-dark): those three rules are deleted, because the label is navy everywhere. The arbitration bar below sets its own ground, border and
   colour after this rule and is untouched. */
.msg-notice {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-md);
  padding: var(--sp-md) var(--sp-lg);
  border-top: 1.5px solid var(--color-gold);
  flex-shrink: 0;
  background: var(--color-cream);
  /* S245 row 139 (Rob, the 9th of October 2026: "you will see that they are different heights and the buttons are different sizes. Every folder should have a section that
     matches the largest one ... That message window footer should be uniform across all folders. That means height, label size, positioning, button size, centreing,
     everything."). HEIGHT. Read off the live page at 1920, the width his five pictures were taken at (the conversation pane is 656px wide): the reply footer (.msg-composer: the
     Inbox, Starred, Offers and every folder with a reply box) stands 67px tall, Sent and Archive 59px, the Bin 64px, Notices 45px, so the reply footer is the largest and every
     strip now takes ITS height. It is built from four numbers, the 12px above, a 42px row (the reply field's height and the round Send button's), the 12px below and the same
     top border, so the row is stated here as the content box's minimum height and not as a total: the strip and the reply footer then come out equal at every screen scale,
     whatever a 1.5px border snaps to. It is a MINIMUM, so a strip whose words or buttons do not fit one row grows to hold them, as it always did. The 42px row also puts the
     label on a whole pixel in every strip: in the Bin's 39px row it sat on a half pixel and its capital stood 0.812px above the strip's middle (0.312px in the others),
     measured from the painted pixels at 8x. POSITION, on a phone: see the wrap in the narrow blocks near the end of the Messages section (the Bin's own wrap, below, is
     unchanged at every width). The arbitration bar below is a card of its own, always taller than the row, wraps already and is unchanged. */
  box-sizing: content-box;
  min-height: 42px;
}
.msg-notice__text {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-sm);
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 13px;
  color: var(--color-navy);
}
/* S244 rows 106 and 113 (Rob, the 8th of October 2026: the footer icon "is not on the same row, it's not centered with the actual text ... use overlays and
   measure by ink", and the bin icon "too low, not centered, doesn't align with the label"). align-items: center above centres the icon's BOX on the label's LINE BOX,
   and the line box is not where the capital letters are. Measured from the painted pixels at 8x against the middle of the label's capital band (first capital top to
   last baseline when the label wraps), the icon's ink centre sat 0.19px below it in one position of the strip and 1.19px below it in the next (0.6 to 1.6px when the
   label wraps at 360), depending only on which fraction of a pixel the strip happens to land on: a text baseline and an SVG box each round to a whole pixel on their
   own. Rob's own picture of the Notices footer reads 1.5px. The fix makes both round together. The label's baseline sits a whole number of pixels below its line's top
   (Chrome rounds the font's ascent and floors the half-leading), so what is needed is an icon top that is also a whole number of pixels below the line's top: a 20px line
   (it was 1.6 x 13 = 20.8px) puts the 15px icon at 2.5px with align-items: center in one line (14.5 in two), and the -1px top margin, which the centring turns into a
   0.5px lift, makes both whole (2 and 14). The last 0.25px is a transform that lifts the painted icon by exactly that much. Result in the same measurement (Notices, Bin
   and Spam, at 1280 and 360, one line or two, at 16 fractions of a pixel and at nine panel heights): the icon's ink centre is between 0.14px above and 0.25px below the
   capital band's middle in every one of them (it was 0.19 to 1.5px below). The strip is 0.8px shorter per label line. Not applied to the arbitration bar, which sets its own
   icon (vertical-align) below and keeps its own line spacing. */
/* S245 row 139: align-self: stretch makes the label's own box the strip's whole content row (the 42px of the strip above, or the wrapped content when it is taller), with the
   icon and the words centred inside it by the label's own align-items: the same pixels as the strip centring a 20px box (11px above and below it, a whole number, so the
   whole-pixel baseline and icon positions below hold), but the label's capital band can now be read against the row it sits in rather than against a strip whose 1px top
   border shifts the box's middle by half a pixel. */
.msg-notice:not(.msg-notice--arbitration) .msg-notice__text { line-height: 20px; align-self: stretch; }
/* S245 row 139 (label size, one in every folder): flex-shrink: 0 keeps the icon its 15px. A flex item shrinks with the label, and at 360, where the label wraps beside the button,
   the Sent strip's paper plane was squeezed to 8.7px wide, Archive's to 8.3px and Notices' to 11.5px while the Bin's stayed 15px (measured on the live page; 15px at 1280 and 1920
   in all of them). The bigger button this row gives Sent and Archive would have squeezed it to 6.9px. The vertical centring above is untouched. */
.msg-notice:not(.msg-notice--arbitration) .msg-notice__text svg { flex-shrink: 0; margin-top: -1px; transform: translateY(-0.25px); }
/* S211 T-S211-021: the Bin footer carries two actions (Restore + Delete for good) side by
   side, and may wrap onto a second line where the panel is narrow. */
.msg-notice--bin { flex-wrap: wrap; }
/* S245 row 139: the actions rule below names every strip but the arbitration bar instead of the Bin alone (the same declarations, replaced in place; the venue-event strip's Message
   and report buttons are its actions too), and a strip's lone button (Move to inbox, Not spam) takes margin-left: auto so that on its own wrapped line (a phone, see the narrow blocks)
   it sits on the right as the Bin's pair does; on one line space-between had put it there already, so nothing moves at 1280 and 1920. */
.msg-notice:not(.msg-notice--arbitration) .msg-notice__actions { display: inline-flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: var(--sp-sm); flex-shrink: 0; max-width: 100%; margin-left: auto; }
.msg-notice:not(.msg-notice--arbitration) > .btn { margin-left: auto; }
/* Delete for good takes the size Restore renders at beside it: 42.8.1 sizes a workspace primary
   at 14px whatever its modifier, so the pair would otherwise differ by 5px.
   S213 item 42 (Rob, 08/09/26: "push this restore label and the icon in front of it down one
   pixel"). 42.8.1 pads a workspace primary 9.5px top against 11.5px bottom, which puts the label
   and the glyph exactly 1px ABOVE the button's centre - measured on the live page, content middle
   1186.08 against button middle 1187.08. Equalised at 10.5px, so the content drops that one pixel
   and the button keeps its 39px height and its neighbour's alignment (BRAND_GUIDE 8.X). Scoped to
   the Bin footer deliberately: the same 2px asymmetry sits on the GLOBAL 42.8.1 rule and therefore
   on every primary and ghost button in the workspace, and moving all of those is Rob's call. */
/* S245 row 139 (Rob: "the buttons should be the size same size in every bottom section"). The Bin's two buttons were the largest a footer button had (14px type on 10.5px 24px,
   39px tall; Move to inbox and Not spam in the other strips were 13px on 8px 16px, 34px tall, from the .btn--sm rule at 42.8.1), so the 14px type is now every footer button's: the
   rule below named the Bin alone and names every strip but the arbitration bar instead (the same two declarations, replaced in place). The padding is 11px, not 10.5px, and the
   button 40px tall, the height of the Compose tab's Save draft button (.msg-compose-draft, height: 40px, S213 item 54): measured from the painted pixels at 8x and device scale 4 at eight sub-pixel positions of
   the page, with 10.5px the capital's middle stands exactly 0.5px from the button's painted middle, 0.5px below it at four positions and 0.5px above at the other four (the
   s238 overlay read the live Restore 0.506px above and Move to inbox 0.631px above), because an odd 39px box and the whole-pixel baseline of a 14px line cannot share a centre;
   with 11px the box and the line are both whole pixels and the capital's middle is 0.000px from the button's middle at all eight. */
#buddypress .workspace .msg-notice:not(.msg-notice--arbitration) .btn.btn--primary,
#buddypress .workspace .msg-notice:not(.msg-notice--arbitration) .btn.btn--danger { padding: 11px 24px !important; font-size: 14px !important; }
/* S244 row 111: the Offers label's own gold-dark colour rule that stood here is deleted; every footer label is navy (see .msg-notice__text). */
.msg-notice--official .msg-notice__text { color: var(--color-navy); }
/* S238 STYLE (Rob, the 27th of September 2026: every new or changed text centred): F40d's refund arbitration bar
   (messages-app.js arbitrationBar(), an administrator's view of an arbitration chat only) is a notice of its own, a
   sentence of up to five lines over a reason field and Issue refund, and it read left-aligned: every wrapped line up to
   210px off the bar's centre at 1280. Its sentence is centred as one block with its icon in the line (so each line
   centres on the bar, not on the space beside the icon), and the reason field and button row centres when it wraps.
   The other notice bars (Spam, Bin, Archive, Offers, the official footer) are unchanged. */
/* ARB-1 (Rob, the 28th of September 2026: "arbitration is in a grey box with no borders"; he chose the look of Lilu's note
   bubble): the bar takes the values of .bubble.bubble--in above (white surface, 1.5px navy border, 16px radius with the
   5px bottom left corner, navy text) and sits inside the chat with the scroll area's own 16px side gutter. The words that
   were a placeholder are a standard .form-label above the field, centred; the rows keep the bar's one gap (12px). */
/* The rows are spaced by what is seen (Rob, the 28th of September 2026: the gaps between rows and the margins above and below are
   uniform): 16px from the border to the capitals of the first line, from each baseline to the capitals or the box under it,
   between the field and the button where they stack, and from the last box to the border. Measured from the picture's own
   pixels at 1280 and 360; the line boxes' own leading is why the declared values differ from 16. */
.msg-notice--arbitration { justify-content: center; flex-wrap: wrap; row-gap: 4px; margin: var(--sp-md) var(--sp-lg); padding: var(--sp-md) var(--sp-lg) 15px; background: var(--color-surface); border: 1.5px solid var(--color-navy); border-radius: 16px; border-bottom-left-radius: 5px; color: var(--color-navy); }
.msg-notice--arbitration .msg-notice__text { display: block; flex: 1 1 100%; text-align: center; }
.msg-notice--arbitration .msg-notice__text svg { display: inline-block; vertical-align: -3px; margin-right: 4px; }
.msg-notice--arbitration .msg-arb-label { display: block; flex: 1 1 100%; margin: 0; text-align: center; }
.msg-notice--arbitration .msg-notice__actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 16px var(--sp-sm); flex: 1 1 100%; margin-top: 4px; }
.msg-notice--arbitration .msg-arb-reason { flex: 1 1 220px; min-width: 0; }

/* =========================================================================
   EMPTY STATES
   ========================================================================= */
.msg-conversation--empty { align-items: center; justify-content: center; }
.msg-empty {
  text-align: center;
  max-width: 320px;
  margin: auto;
  padding: var(--sp-2xl);
  color: var(--color-text-secondary);
}
.msg-empty__glyph {
  display: inline-grid;
  place-items: center;
  width: 72px; height: 72px;
  border-radius: 50%;
  background: var(--color-cream);
  border: 1.5px solid var(--color-gold);
  color: var(--color-gold-dark);
  margin-bottom: var(--sp-lg);
}
.msg-empty__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 18px;
  color: var(--color-navy);
  margin-bottom: var(--sp-lg);
}
.msg-empty p { font-size: 14px; line-height: 1.5; margin: 0; text-wrap: pretty; }
.msg-empty--list { color: var(--color-text-muted); }
.msg-empty--list svg { color: var(--color-gold); margin-bottom: var(--sp-sm); }
/* S245 row 74 (Rob, the 7th of October 2026, D-789: "on the side panel in the inbox folder underneath the star there are three rows of text whereas everywhere else only has two and as a result it
   pushes the top row up one and the star up one. That's wrong. The star should be in exactly the same place on every side panel for every folder, and if there's an extra row of text, it should be
   added on at the bottom. It shouldn't push all the content up."). MEASURED live on an account whose folders are empty, at 1280, 1024, 768 and 360: the empty panel is .msg-empty, whose
   margin: auto (above) centres it in the flex column .msg-thread-scroll, so how high the block starts depends on how tall it is, and it is as tall as its copy. The Inbox copy ("No messages yet. When
   you match or share an event, your conversations land here.") wraps to three rows (63px) where the copy of every other folder wraps to two (42px), so the Inbox block was 21px taller, its two auto
   margins 10.5px smaller each, and its star painted higher: ink centre 164.00px against 175.00px from the top of the list at 1280 (11px, read off the painted pixels at 4x; 10.5px by the boxes).
   The paragraph after the icon now keeps the height of two rows whatever it holds (two rows of the 1.5 line-height set on .msg-empty p above, which is 3em, or 2lh where the browser has the lh
   unit), so the block is the same height in every folder and centres in the same place; a third row hangs below it, inside the block's own 32px bottom padding. The six other folders do not
   move (their block is two rows already); only the Inbox does. Scoped to the paragraph that follows the icon inside the side panel (svg + p in .msg-thread-scroll), so the Compose picker's
   own short messages (no icon) and the load-error box (outside .msg-thread-scroll) are untouched. */
.msg-thread-scroll > .msg-empty--list > svg + p { height: 3em; height: 2lh; }

/* action-result confirmations (Archive / Spam / Delete) */
.msg-conversation--result .msg-empty__glyph--archived {
  color: var(--color-success);
  border-color: var(--color-success);
  background: var(--color-success-bg);
}
.msg-conversation--result .msg-empty__glyph--spam {
  color: var(--color-warning);
  border-color: var(--color-warning);
  background: var(--color-warning-bg, #fff7e6);
}
.msg-conversation--result .msg-empty__glyph--deleted {
  color: var(--color-error);
  border-color: var(--color-error);
  background: var(--color-error-bg);
}
.msg-empty .msg-result-undo { margin-top: var(--sp-lg); } /* S227 items 47+50: scope-bumped past .workspace .btn{margin:0}, which was zeroing this and putting Undo hard against the text */

/* compose card holds a steady height so swapping form ↔ "sent" doesn't jump */
.msg-compose-card { min-height: 512px; display: flex; flex-direction: column; }
/* S219 (Rob 10/09/26): "really quite expanded it's like an exploded view. Put the To and the subject on the same
   row down to 1024 width, then it can be vertically stacked as it is now. Reduce all the gaps between each input
   field, And make them all uniform... the three lines that show that it can be expanded are black. You can make
   them blue." One even 12px step between fields, 6px between a label and its field, the theme's 18px input
   margin removed, To and Subject side by side from 1024 up, and a navy resize grip. */
.msg-compose-card .form-grid { flex: 0 0 auto; row-gap: 12px; }
.msg-compose-card .form-row .form-label { margin-bottom: 6px; }
.msg-compose-card .form-row .form-input,
.msg-compose-card .form-row .form-textarea,
.msg-compose-card .form-row .msg-to-field { margin-bottom: 0 !important; }
.msg-compose-card .form-row .form-hint { margin-top: 6px; }

.msg-compose-card .form-textarea::-webkit-resizer { background: url(data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2010%2010%27%3E%3Cpath%20d%3D%27M9.5%201%20L1%209.5%20M9.5%204.5%20L4.5%209.5%20M9.5%208%20L8%209.5%27%20stroke%3D%27%23031B83%27%20stroke-width%3D%271.3%27%20stroke-linecap%3D%27round%27%2F%3E%3C%2Fsvg%3E) no-repeat center / 10px 10px; }
.msg-compose-success {
  margin: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.msg-compose-success .msg-empty__glyph--success {
  color: var(--color-success);
  border-color: var(--color-success);
  background: var(--color-success-bg);
}

/* =========================================================================
   COMPOSE TAB
   ========================================================================= */
.msg-compose-wrap { max-width: 640px; margin: 0 auto; }
/* Inherits the centred form defaults from styles.css (labels, inputs,
   placeholders all centred) — matches the rest of the dashboard. */
.msg-compose-body { resize: vertical; min-height: 140px; font-family: var(--font-body); line-height: 1.55; }

/* Actions row: Send sits dead-centre of the card, Save draft on the right,
   both vertically aligned on one row. 3-col grid (1fr | auto | 1fr) keeps
   the primary optically centred regardless of the draft button's width. */
/* S227 (VC cloud 01, 15/09/26), items 114 and 115. This block was being thrown away:
   `.workspace .form-actions` (0,2,0) sets display:flex and gap:var(--sp-sm) and outranks
   `.msg-compose-actions` (0,1,0), so the live row computed as a flex row with an 8px gap and
   every grid-column and justify-self below was inert, including the phone stacking rule. The
   selector is scoped up to beat it, which BRAND_GUIDE 9.7 point 4 allows and which leaves the
   shared .form-actions rule alone for every other form in the workspace. Nothing in the body
   of the rule changes. */
/* S229 16/09/26, Rob on the live pictures: "There should be a save draft button above the send
   message button, both centered as per that solution." The S227 three-column grid put Send in
   the middle column with Save draft off to the right; this puts the pair back to one centred
   column at every width, Save draft first. The DOM order is Send then Save draft, so the two
   order values below do the swap without touching messages-app.js. */
.workspace .form-actions.msg-compose-actions {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 15px;
  margin-top: var(--sp-lg);
}
/* S229: no order values here. The workspace's own .form-actions rule is column-REVERSE, so the
   DOM order (Send then Save draft) already paints Save draft on top, which is what Rob asked
   for. Setting order put Send back on top. */
/* S213 item 55 (Rob 08/09/26: "the send message button is a bit wide. It could be maybe fifteen
   percent thinner"). It took a 220px minimum from the shared `.workspace .form-actions .btn`
   rule, so the fifteen percent is set HERE rather than on that rule - every other form-actions
   button in the workspace keeps the width it was given. 220 less fifteen percent is 187. */
.msg-compose-send  { grid-column: 2; justify-self: center; }
/* S215 (MSG-14): equalised to 10.5px so the label drops the one pixel onto the button centre,
   exactly as S213 item 42 did for the Bin footer pair at 42.11. The same 2px asymmetry sits on
   the global 42.8.1 rule and therefore on every primary and ghost button in the workspace;
   moving all of those is a decision for Rob (T-S213-031), so this stays per-button. */
#buddypress .workspace .form-actions .btn.msg-compose-send { min-width: 187px !important; width: 187px !important; padding: 10.5px 24px !important; }
/* !important because the shared rule it overrides carries min-width: 220px !important and
   width: auto !important; higher specificity alone cannot beat an important declaration. */
/* Save draft sits immediately to the right of the centred Send button
   (the 15px grid gap is the only space between them). Styled like the menu
   pills: white surface, gold border, raised drop-shadow, presses flat. */
.msg-compose-draft {
  grid-column: 3;
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.02em;
  color: var(--color-navy);
  background: var(--color-surface);
  border: 1px solid var(--color-gold);
  border-radius: 10px;
  /* S213 item 54 (Rob 08/09/26: "the save draft button is the wrong shape. It's too tall... It
     should be the same height [as] the button below it"). Its 10px vertical padding put it at
     42.8px against Send message's 40. Pinned to 40 with the padding taken off the vertical axis,
     so the pair reads as one row whatever the label. */
  height: 40px;
  padding: 0 18px;
  box-shadow: var(--shadow-gold-hover);
  transform: translateY(-1px);
  transition: transform 120ms var(--ease-out),
              box-shadow 120ms var(--ease-out),
              background-color 120ms var(--ease-out),
              color 120ms var(--ease-out),
              border-color 120ms var(--ease-out);
}
.msg-compose-draft:hover { background: var(--color-surface); }
.msg-compose-draft:active {
  transform: translateY(0);
  box-shadow: none;
  transition-duration: 50ms;
}
/* Pressed/confirmed. S227 (VC cloud 01, 15/09/26), item 115. Rob: "As for the saved state,
   that should obviously be using the greens again. That's been mentioned many times before."
   It was navy on white, which is the same as the unsaved state, so nothing told him it had
   saved except the word. This is the platform's selected/positive set. */
.msg-compose-draft--saved {
  color: #2F6B47;
  background: #EAF4EC;
  border-color: #2F7D4F;
}
.msg-compose-draft--saved:hover { background: #EAF4EC; }
@container vp (max-width: 599px) {
  /* Stack on phone — Send on top, Save below, both centred. */
  .msg-compose-actions { grid-template-columns: 1fr; }
  .msg-compose-send  { grid-column: 1; }
  .msg-compose-draft { grid-column: 1; justify-self: center; }
}

/* =========================================================================
   RESPONSIVE — narrow viewport (≤600): panels stack, conversation slides
   over the list (single-pane, like mobile). Side-by-side with the drag
   handle applies from 601px up.
   ========================================================================= */
@container vp (max-width: 600px) {
  .msg-split {
    flex-direction: column;
    height: clamp(520px, 78vh, 760px);
  }
  .msg-thread-list { width: auto; }
  .msg-resizer { display: none; }
  /* S245 row 139: every footer strip wraps on a phone, as the Bin's has at every width (.msg-notice--bin above): measured at 360, a strip with a button broke its label into three or four
     short lines beside the button and squeezed its icon; now the label keeps one line and the button drops to its own line on the right. Wider than this nothing wraps that did not. */
  .msg-notice { flex-wrap: wrap; }
  /* default: show list, hide conversation */
  .msg-split .msg-conversation { display: none; }
  .msg-split .msg-thread-list { display: flex; }
  /* conversation open: hide list, show conversation full-width */
  .msg-split--mobile-convo .msg-thread-list { display: none; }
  .msg-split--mobile-convo .msg-conversation { display: flex; }
  /* back button visible on narrow */
  .msg-back { display: grid; }
  /* S245 row 131 (Astra, the 9th of October 2026, the item 24 proof: "the heading is squeezed into a narrow column beside its normal action icons, the name cut to one letter
     and the tier word printing one letter per line"). Read off the live page at 360 (results/s245/wf-visual/messages/m2_before_head_sent.json): the head is ONE flex row that cannot
     wrap, and the back button 36 + the sigil 42 + the four icons 150 + three 12px gaps leave the name column 12.5px wide of a 308.5px panel (the name is 181px wide, so it showed as
     a single letter; the tier word "Member" broke into one letter per line, a 5-line column); the same column is 26px at 375, 39.5px at 390, 61px at 414 and 75.5px at 430. The head
     may wrap now: the name column asks for 120px (the longest tier phrase, "Official notice", is 79.4px wide at 12px/600 and a name at 16px/700 takes about 8.6px a letter, so
     120px keeps the phrase on one line and shows about fourteen letters of the name), and when the icons would leave it less than that they drop onto a line of their own, on the
     right as they sit on a wide panel (margin-left: auto, the way the Bin footer's wrapped buttons sit on the right). The icons keep their 36px size, their 2px gap and their order,
     the markup is untouched, and at 480 and wider the column is still 120px or more, so the head stays one row there exactly as it was. In the phone block only: the two-pane layout
     (a container wider than 600px) is not touched.
     One more line is needed for the wrapped line to look right: Seeko's button rule, margin-bottom: 1rem (seeko-dynamic.css, 0,0,1; the same stray margin S244 row 116 reset on the
     Send button) gives the back button and each of the four icons 16px of blank under them, which was hidden while the icons shared the sigil's line (the icons' box was 52px
     tall and sat 8px above the line's middle) and would now be 16px of empty strip under the icons' own line and a back arrow 8px above the sigil's middle; the two rules
     take it back to 0 on a phone, so the arrow, the sigil and the name share one middle and the icons' line is as tall as the icons. */
  .msg-conv-head { flex-wrap: wrap; }
  .msg-conv-head__text { flex: 1 1 120px; }
  .msg-conv-head__actions { margin-left: auto; }
  .msg-back, .msg-conv-head__action { margin-bottom: 0; }
  .bubble-row { max-width: 86%; }
}

/* Fallback for real narrow browsers (no container support / fit mode). */
@media (max-width: 600px) {
  .msg-split {
    flex-direction: column;
    height: clamp(520px, 78vh, 760px);
  }
  .msg-thread-list { width: auto; }
  .msg-resizer { display: none; }
  /* S245 row 139: the same wrap as the container block above (its fallback for a browser without container queries). */
  .msg-notice { flex-wrap: wrap; }
  .msg-split .msg-conversation { display: none; }
  .msg-split--mobile-convo .msg-thread-list { display: none; }
  .msg-split--mobile-convo .msg-conversation { display: flex; }
  .msg-back { display: grid; }
  /* S245 row 131: the same three declarations as the container block above (this is its fallback for a browser without container queries). */
  .msg-conv-head { flex-wrap: wrap; }
  .msg-conv-head__text { flex: 1 1 120px; }
  .msg-conv-head__actions { margin-left: auto; }
  .msg-back, .msg-conv-head__action { margin-bottom: 0; }
}
/* 44.F23 Folder unread marker (S238 26/09/2026, F23, ruled final: "each folder pill in the Messages
   workspace carries a small green tick marker when that folder holds unread items, so the member knows
   where"). The D-181 notification idiom, the same light-green fill, green ring and green tick as the
   sidenav badge (41.8), at pill scale. It sits on the pill's top-right corner and is positioned
   absolutely, so the pill keeps its own size and the label does not move: the pill row never shifts as
   markers come and go when a folder is read. Painted only on a pill that holds unread conversations
   (messages-app.js adds the --has-unread class and the marker together). Never a number (D-288). */
.uks-messages .section-nav__item--has-unread { position: relative; }
.uks-messages .section-nav__tick {
  position: absolute;
  top: -6px;
  right: -6px;
  box-sizing: border-box;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(var(--color-success-bg), var(--color-success-bg)), #FFFFFF;
  border: 1.5px solid var(--color-success);
  color: var(--color-success);
  line-height: 1;
  pointer-events: none;
}
.uks-messages .section-nav__tick svg { display: block; width: 9px; height: 9px; }
/* end of 44.F23 */
/* end of 44 */

/* ============================================================================
   45. SECTION: Preferences page — design-agent port (Preferences.html, 2026-06-04)
   Ported VERBATIM from design_handoff_preferences/preferences.css. Two states:
   .pf-wizard (questionnaire) and .pf-complete (results summary).
   The container-query root (#item-body, container-name: vp) is already
   established at §42.0, so the design's @container vp rules below fire as-is.
   ============================================================================ */

/* 45.0 Design-agent token values, scoped to the preferences page containers so
   the page renders with the design agent's EXACT values (not whatever the live
   :root resolves to). Custom properties inherit to every .pf-* descendant.
   Values copied verbatim from design_handoff_preferences/styles.css :root. */
.pf-wizard,
.pf-complete {
  --color-navy: #031B83;
  --color-gold: #CC9900;
  --color-gold-dark: #80641D;
  --color-cream: #FFFBE6;
  --color-surface: #FFFFFF;
  --color-surface-raised: #F8F7F4;
  --color-surface-sunken: #F3F2EF;
  --color-text-secondary: rgba(3, 27, 131, 0.75);
  --color-text-muted: rgba(3, 27, 131, 0.65);  /* S229 (T-S215-009 d), Rob: navy at 55 per cent reads grey; 65 reads blue. */
  --color-border-strong: rgba(26, 26, 46, 0.15);
  --color-success: #27A644;
  --color-success-bg: rgba(39, 166, 68, 0.08);
  --color-error: #C41C1C;
  --radius-md: 16px;
  --radius-pill: 9999px;
  --shadow-sm: 0 1px 2px rgba(26, 26, 46, 0.04), 0 2px 4px rgba(26, 26, 46, 0.04);
  --shadow-md: 0 2px 4px rgba(26, 26, 46, 0.04), 0 4px 12px rgba(26, 26, 46, 0.08);
  --shadow-gold-hover: 0 4px 12px rgba(0, 0, 0, 0.16);
  /* D-655 25/09/2026: black, not gold, Rob; the name is kept so nothing else breaks. */
  --font-heading: 'Montserrat', system-ui, sans-serif;
  --font-body: 'Nunito Sans', system-ui, sans-serif;
  --duration-fast: 150ms;
  --duration-normal: 250ms;
  --ease-out: cubic-bezier(0.25, 1, 0.5, 1);
  --sp-xs: 4px;
  --sp-sm: 8px;
  --sp-md: 12px;
  --sp-lg: 16px;
  --sp-xl: 24px;
  --sp-2xl: 32px;
  --sp-3xl: 48px;
}

/* 45.1 ---- preferences.css VERBATIM (design handoff) ---- */
.pf-wizard,
.pf-complete {
  max-width: 720px;
  margin: 0 auto;
  font-family: var(--font-body);
}

/* ---- Back-to-summary link (edit mode) ---------------------------------- */
.pf-backlink {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: 0;
  cursor: pointer;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 13px;
  color: var(--color-text-muted);
  padding: 6px 0;
  margin-bottom: var(--sp-md);
  transition: color var(--duration-fast) var(--ease-out);
}
.pf-backlink:hover { color: var(--color-navy); }

/* =========================================================================
   WIZARD — progress track
   ========================================================================= */
.pf-progress {
  margin: 0 0 15px;
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  padding: var(--sp-md) var(--sp-lg);
}
.pf-progress__meta {
  display: flex;
  justify-content: space-between;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-navy);
  margin-bottom: var(--sp-sm);
}
.pf-progress__meta span:last-child { color: var(--color-gold); }
.pf-progress__track {
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  gap: 5px;
}
.pf-progress__seg {
  height: 7px;
  border-radius: var(--radius-pill);
  background: var(--color-cream, #FFFBE6);
  border: 1px solid var(--color-gold, #CC9900);
  transition: background var(--duration-normal) var(--ease-out);
}
.pf-progress__seg.is-done { background: var(--color-gold); }
.pf-progress__seg.is-now  {
  background: var(--color-navy);
  border-color: var(--color-gold, #CC9900);
  box-shadow: 0 0 0 2px rgba(204, 153, 0, 0.22);
}

/* =========================================================================
   WIZARD — section header
   ========================================================================= */
.pf-sec-head { text-align: center; margin-bottom: var(--sp-xl); }
.pf-sec-head__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-gold);
  margin-bottom: var(--sp-sm);
}
.pf-sec-head__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  margin: 0 auto var(--sp-sm);
  font-size: 24px;
  line-height: 1;
  background: var(--color-cream);
  border: 2px solid var(--color-gold);
  border-radius: 50%;
  box-shadow: var(--shadow-sm);
}
.pf-sec-head__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 30px;
  line-height: 1.15;
  color: var(--color-navy);
  margin: 0 0 var(--sp-sm);
}
.pf-sec-head__desc {
  font-size: 15px;
  line-height: 1.55;
  color: var(--color-text-secondary);
  max-width: 52ch;
  margin: 0 auto var(--sp-md);
  text-wrap: pretty;
}

/* Privacy badge (shared by wizard + tiles) */
.pf-privacy {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 14px;
  border-radius: var(--radius-pill);
  font-size: 12.5px;
  font-weight: 600;
  border: 1px solid;
}
.pf-privacy--private {
  color: #C41C1C;
  background: rgba(192, 57, 43, 0.06);
  border-color: rgba(192, 57, 43, 0.45);
}
.pf-privacy--visible {
  color: var(--color-text-muted);
  background: var(--color-surface-raised);
  border-color: var(--color-border-strong);
}
.pf-privacy svg { flex-shrink: 0; }

/* =========================================================================
   WIZARD — question card
   ========================================================================= */
.pf-qcard {
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  padding: var(--sp-2xl);
  text-align: center;
  animation: pf-rise var(--duration-normal) var(--ease-out);
}
@keyframes pf-rise {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
.pf-qcard__counter {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: var(--sp-sm);
}
.pf-qcard__text {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 21px;
  line-height: 1.3;
  color: var(--color-navy);
  margin: 0 0 var(--sp-xl);
  text-wrap: pretty;
}
.pf-req { color: var(--color-error); margin-left: 3px; }

/* ---- Slider ------------------------------------------------------------ */
.pf-slider { padding: var(--sp-sm) 0; }
.pf-slider__ends {
  display: flex;
  justify-content: space-between;
  gap: var(--sp-md);
  font-weight: 600;
  font-size: 13px;
  color: var(--color-text-secondary);
  margin-bottom: var(--sp-md);
}
.pf-slider__ends span:last-child { text-align: right; }
/* S231 18/09/26 (triage item 53), Rob: "there is a much neater branded version of this on the time
   selector drop downs on the other event page... the rail on the time radio does not have a simple
   plain grey background like this slider does. So copy that instead." The rail is copied from
   .ev-scroller__track and .ev-scroller__thumb (page-polish 20639): a white rail inside a 1.5px
   #E0C56A border with a pill radius, filled in the scroller thumb's #DDB94B rather than the plain
   #F3F2EF grey. This is the platform's one range control, so the questionnaire takes it too. */
.pf-slider__range {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 12px;
  box-sizing: border-box;
  border: 1.5px solid #E0C56A;
  border-radius: var(--radius-pill);
  outline: none;
  /* S231 18/09/26, second pass. Rob: "on the slider, where it's gold, give it a blue border. And
     then where it's empty, leave it as the gold border." A border cannot be two colours along its
     length, so the element keeps the gold border for the empty part and the FILLED part draws its
     own navy edge in the background: a 1.5px navy line along the top and the bottom of the filled
     run, and a 1.5px navy cap at the left end. The right end needs none, the thumb sits there.
     S245 row 83 (Rob, the 7th of October 2026, on the Minimum proximity distance slider: "the blue border at the bottom of that slider is thinner than on the top"; D-805): the three lines
     below are 2px, not 1.5px. MEASURED LIVE on the invites page (the slider is this rail) with the rail moved through four fractional vertical positions at 100 per cent: a 1.5px line
     is painted as two rows or one depending on where the rail falls on the page, and the top and bottom lines snap independently, so the bottom came out one row (1.00) against the top's
     1.5 at two of the four positions (Rob's own picture: top 2 rows, bottom 1) and the pair is never guaranteed to match. At 2px both lines are 2.00 at every position tested, at
     100 per cent and at 200 per cent. The gold border and the 12px height are untouched. */
  background:
    linear-gradient(to right, #031B83 0, #031B83 var(--fill, 50%), transparent var(--fill, 50%)) top left / 100% 2px no-repeat,
    linear-gradient(to right, #031B83 0, #031B83 var(--fill, 50%), transparent var(--fill, 50%)) bottom left / 100% 2px no-repeat,
    linear-gradient(#031B83, #031B83) left top / 2px 100% no-repeat,
    linear-gradient(
      to right,
      #DDB94B 0%,
      #DDB94B var(--fill, 50%),
      #FFFFFF var(--fill, 50%),
      #FFFFFF 100%
    );
  cursor: pointer;
}
.pf-slider__range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--color-navy);
  border: 3px solid var(--color-surface);
  box-shadow: var(--shadow-md);
  cursor: pointer;
}
.pf-slider__range::-moz-range-thumb {
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--color-navy);
  border: 3px solid var(--color-surface);
  box-shadow: var(--shadow-md);
  cursor: pointer;
}
/* S231 18/09/26 (triage item 53), Rob: "The distance text numbers should be bold, like the
   titles." The value under the rail was muted and at the body weight. */
.pf-slider__lean {
  text-align: center;
  margin-top: var(--sp-lg);
  font-size: 13px;
  font-weight: 700;
  color: var(--color-navy);
}
.pf-slider__lean strong { color: var(--color-navy); }
/* S245 row 82 (Rob, the 7th of October 2026, on the Minimum proximity distance slider: "the distance numbers should all be a 50% bigger and gold"; D-805). The numbers are 0 m and 1000 m
   (.pf-slider__ends, 13px, navy at 75 per cent) and the chosen value under the rail (.pf-slider__lean, 13px, navy), MEASURED LIVE on the invites page. 13px x 1.5 = 19.5px, in --color-gold
   (#CC9900). Scoped to the proximity slider's own wrapper (.ei-proximity__control, mu-plugins/invite-system.php 8.3.4a): the questionnaire's sliders share .pf-slider and Rob named only this one. */
.ei-proximity__control .pf-slider__ends,
.ei-proximity__control .pf-slider__lean {
  font-size: 19.5px;
  color: var(--color-gold);
}

/* ---- Scale 1–5 --------------------------------------------------------- */
.pf-scale { display: flex; gap: var(--sp-sm); }
.pf-scale__opt {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: var(--sp-md) var(--sp-sm) var(--sp-md);
  background: var(--color-surface);
  border: 2px solid var(--color-gold);
  border-radius: 12px;
  cursor: pointer;
  text-align: center;
  transition: transform var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out);
}
/* background added (design base value) to defeat Seeko's `button:hover{background:#f0f0f0}` (0,1,1) — our :hover is 0,2,0 so it wins without !important. */
.pf-scale__opt:hover { border-color: var(--color-gold); transform: translateY(-2px); box-shadow: var(--shadow-gold-hover); background: var(--color-surface); }
.pf-scale__num {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 20px;
  color: var(--color-navy);
  width: 38px; height: 38px;
  /* S245 row 56 (Rob, the 7th of October 2026: "the numbers sit low in the circles ... Is this stacked CSS rules or something?"; LABELS-1). This is the ONLY rule that sets the circle, so nothing is
     stacked: the digit is simply 1px low. The circle is a grid that centres the digit's 32px line box (the inherited 1.6 on 20px) in a 34px content box. MEASURED LIVE on
     example_aaron_fitzgerald's step 6 question 3 (Segoe UI Bold: Montserrat is named in the font stack but never loaded): the digit's painted rows sit 1.03px below the circle's centre at 100 per
     cent (14 rows), and 0.88 to 1.13px low by the comparison engine's own capture (scale 8) at 1280 and 1920, 1.00 to 1.25px at 768 and 1024. padding-bottom 2px takes 2px off the content box,
     which leaves exactly the 32px line box, so the line moves up one whole pixel and its offset inside the box becomes 0, a whole number: where the circle falls on the page then no longer
     changes where the digit snaps. Measured with it: 1280 -0.13, -0.13, 0.00, 0.13 (circles 1, 2, 4, 5, engine capture) and 0.03 at 100 per cent; 1920 and 768 within 0.25; 1024 0.25 to 0.50.
     At 360, where the five answers wrap onto separate rows at fractional heights (112.375px apart), the first circle measures -0.50, the fourth -0.13 and the fifth +0.63 (live: +0.50, +0.88, +1.63). */
  padding-bottom: 2px;
  display: grid; place-items: center;
  border-radius: 50%;
  /* Rob S135: unchosen numbers are the normal brand circle (cream + gold border);
     only the chosen one goes green (.is-sel rule below). Was --color-surface-raised
     (grey) with no border, which also made the circle jump size on selection. */
  background: var(--color-cream);
  border: 2px solid var(--color-gold);
  box-sizing: border-box;
  transition: all var(--duration-fast) var(--ease-out);
}
.pf-scale__lbl {
  font-size: 11.5px;
  line-height: 1.25;
  font-weight: 600;
  color: var(--color-text-secondary);
}
.pf-scale__opt.is-sel {
  border-color: #2F7D4F;
  background: #EAF4EC;
}
.pf-scale__opt.is-sel .pf-scale__num { background: #EAF4EC; color: #2F7D4F; border: 2px solid #2F7D4F; }
.pf-scale__opt.is-sel .pf-scale__lbl { color: #2F6B47; }

/* ---- Single choice ----------------------------------------------------- */
.pf-options { display: flex; flex-direction: column; gap: var(--sp-sm); }
.pf-opt {
  display: flex;
  align-items: center;
  gap: var(--sp-md);
  padding: 15px var(--sp-lg);
  background: var(--color-surface);
  border: 2px solid var(--color-gold);
  border-radius: 12px;
  cursor: pointer;
  text-align: left;
  transition: border-color var(--duration-fast) var(--ease-out),
              background var(--duration-fast) var(--ease-out);
}
.pf-opt:hover { border-color: var(--color-gold); background: var(--color-surface-raised); }
.pf-opt__text {
  flex: 1;
  min-width: 0;
  font-size: 15px;
  font-weight: 600;
  color: var(--color-navy);
  overflow-wrap: anywhere;
  word-break: break-word;
}
.pf-opt__radio {
  position: relative;
  width: 22px; height: 22px;
  border-radius: 50%;
  border: 2px solid var(--color-gold);
  flex-shrink: 0;
  transition: border-color var(--duration-fast) var(--ease-out);
}
.pf-opt__radio::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 10px; height: 10px;
  border-radius: 50%;
  background: #2F7D4F;
  transform: scale(0);
  transition: transform var(--duration-fast) var(--ease-out);
}
.pf-opt.is-sel { border-color: #2F7D4F; background: #EAF4EC; }
.pf-opt.is-sel .pf-opt__text { color: #2F6B47; }
.pf-opt.is-sel .pf-opt__radio { border-color: #2F7D4F; }
.pf-opt.is-sel .pf-opt__radio::after { transform: scale(1); }

/* ---- Multi-select chips ------------------------------------------------ */
.pf-chips { display: flex; flex-wrap: wrap; gap: var(--sp-sm); justify-content: center; }
.pf-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 10px 16px;
  background: var(--color-surface);
  border: 2px solid var(--color-gold);
  border-radius: var(--radius-pill);
  cursor: pointer;
  font-size: 14px;
  font-weight: 600;
  color: var(--color-navy);
}
.pf-chip:hover { border-color: var(--color-gold); color: var(--color-navy); background: var(--color-surface); }
.pf-chip__tick {
  display: inline-grid; place-items: center;
  width: 16px; height: 16px;
  border-radius: 50%;
  background: var(--color-gold);
  color: var(--color-navy);
}
.pf-chip.is-sel {
  background: #EAF4EC;
  border-color: #2F7D4F;
  color: #2F6B47;
}
.pf-chip.is-sel .pf-chip__tick { background: #2F7D4F; color: #fff; }

/* ---- Yes / No ---------------------------------------------------------- */
.pf-yesno { display: flex; gap: var(--sp-md); }
.pf-yesno__opt {
  flex: 1;
  padding: 18px;
  background: var(--color-surface);
  border: 2px solid var(--color-gold);
  border-radius: 12px;
  cursor: pointer;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 16px;
  color: var(--color-navy);
  transition: border-color var(--duration-fast) var(--ease-out),
              background var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-out);
}
.pf-yesno__opt:hover { border-color: var(--color-gold); transform: translateY(-2px); background: var(--color-surface); color: var(--color-navy); }
.pf-yesno__opt.is-sel { border-color: #2F7D4F; background: #EAF4EC; color: #2F6B47; }

/* Defeat Seeko's pressed-button grey flash. seeko-dynamic.css applies
   `button:not([disabled]):not(.disabled):active` (spec 0,3,1) → bg #eee,
   border transparent, colour #191919 — a grey flash while an option is clicked.
   The :hover fixes above (0,2,0) handle pure hover but can't outrank :active.
   Restore the design's pressed = hover look, scoped #buddypress .workspace
   (1,3,0 / 1,4,0) so it beats Seeko's :active; selected options keep their green. */
#buddypress .workspace .pf-scale__opt:active,
#buddypress .workspace .pf-chip:active,
#buddypress .workspace .pf-yesno__opt:active {
  background: var(--color-surface);
  border-color: var(--color-gold);
  color: var(--color-navy);
}
#buddypress .workspace .pf-opt:active {
  background: var(--color-surface-raised);
  border-color: var(--color-gold);
}
#buddypress .workspace .pf-scale__opt.is-sel:active,
#buddypress .workspace .pf-chip.is-sel:active,
#buddypress .workspace .pf-yesno__opt.is-sel:active,
#buddypress .workspace .pf-opt.is-sel:active {
  background: #EAF4EC;
  border-color: #2F7D4F;
  color: #2F6B47;
}

/* =========================================================================
   WIZARD — navigation
   ========================================================================= */
/* S135 (Rob 19/07/26): "Do not allow next without an answer chosen." Inline prompt
   shown on the question card when Next is pressed with nothing selected. Brand error
   colour, no native dialog (D-220). Hidden until the JS reveals it. */
.pf-answer-required {
  display: none;
  margin: var(--sp-md) 0 0;
  font-family: var(--font-body);
  font-size: 13.5px;
  font-weight: 600;
  color: var(--color-error);
  text-align: center;
}

/* S135 (Rob 19/07/26): "Back to summary" was 33.8px LEFT of true centre (measured,
   not eyeballed). Cause: flex + space-between with `margin: 0 auto` centres the
   middle item between its two siblings, and the Back button (112px) is much
   narrower than the Skip+Next group (179px) - so it sat half that difference to the
   left. A 3-column grid with EQUAL 1fr outer tracks makes the middle item dead
   centre in the nav no matter how wide the side groups are. */
.pf-nav {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--sp-md);
  margin-top: var(--sp-xl);
}
.pf-nav > :first-child { justify-self: start; }
.pf-nav__right { display: flex; align-items: center; gap: var(--sp-sm); justify-self: end; }
.pf-nav__summary {
  justify-self: center;
  margin: 0;
}
/* Rob 19/07/26: this link is gold, not navy. He first picked light gold (#FFD700)
   then corrected it - "Can't read the 'back to summary' in that gold, use the darker
   one" - so it is the standard brand gold #CC9900. Needs the `.btn` qualifier:
   `.btn.btn--subtle` (0,2,0) sets navy, so a bare `.pf-nav__summary` (0,1,0) would
   lose; same specificity + later source order wins. Scoped to this one link so the
   shared .btn--subtle (Skip, and others site-wide) is untouched. */
.btn.pf-nav__summary,
.btn.pf-nav__summary:hover,
.btn.pf-nav__summary:focus {
  color: var(--color-gold);
}
@media (max-width: 768px) {
  /* Stack: Back + Skip/Next on row 1, the summary link centred on its own row. */
  .pf-nav { grid-template-columns: auto auto; row-gap: var(--sp-md); }
  .pf-nav__summary { order: 99; grid-column: 1 / -1; justify-self: center; text-align: center; margin: 0; }
}
.pf-btn-next {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 26px;
  background: var(--color-navy);
  color: var(--color-gold);
  border: 2px solid var(--color-navy);
  border-radius: 10px;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 14px;
  cursor: pointer;
  transition: transform var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out);
}
.pf-btn-next:hover { transform: translateY(-1px); box-shadow: 0 4px 14px rgba(3, 27, 131, 0.22); }
/* S222: the profile wizard's Back button. The comment on the very next rule already records
   that this washed-out look "made it look missing"; that rule fixed one button, this fixes the
   rest. COMPUTED before: rgb(154,164,205) on white, 2.45 to 1. pointer-events stays off. */
.btn[disabled] { opacity: 1; cursor: not-allowed; pointer-events: none; }

/* Keep the wizard Back button clearly visible even when disabled on the
   first question — the global washed-out disabled style made it look missing. */
.pf-nav .btn--primary:disabled,
.pf-nav .btn--primary.btn--disabled {
  background: transparent;
  border-color: var(--color-gold);
  color: var(--color-navy);
  opacity: 1;
}

/* =========================================================================
   COMPLETED — result hero
   ========================================================================= */
.pf-complete { display: flex; flex-direction: column; gap: var(--sp-xl); }

.pf-hero {
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  padding: var(--sp-xl);
  overflow: hidden;
}
.pf-hero__top {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-md);
  margin-bottom: var(--sp-xl);
  text-align: center;
}
.pf-hero__check {
  flex-shrink: 0;
  width: 46px; height: 46px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--color-success);
  color: #fff;
  box-shadow: 0 4px 12px rgba(39, 166, 68, 0.28);
}
.pf-hero__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 24px;
  color: var(--color-navy);
  margin: 0 0 2px;
}
.pf-hero__sub {
  font-size: 14px;
  color: var(--color-text-secondary);
  margin: 0;
  text-wrap: pretty;
}

/* Result band — cream bg, navy text */
.pf-result {
  display: flex;
  align-items: center;
  gap: var(--sp-lg);
  padding: var(--sp-lg) var(--sp-xl);
  background: var(--color-cream);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  color: var(--color-navy);
}
.pf-result__emoji {
  flex-shrink: 0;
  font-size: 38px;
  line-height: 1;
  width: 76px; height: 76px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: #fff;
  border: 2px solid var(--color-gold);
}
.pf-result__body { display: flex; flex-direction: column; gap: 2px; flex: 1; }
.pf-result__eyebrow {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 10.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-gold-dark);
}
.pf-result__label {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 26px;
  line-height: 1.05;
  color: var(--color-navy);
}
.pf-result__desc { font-size: 13.5px; color: var(--color-text-secondary); }
.pf-result__signal {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  padding-left: var(--sp-lg);
  border-left: 1px solid rgba(3, 27, 131, 0.12);
}
.pf-result__signal-row {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11px; font-weight: 600;
  color: var(--color-text-muted);
}
.pf-result__signal-val {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 22px;
  color: var(--color-navy);
}
.pf-result__signal-val span { font-size: 13px; color: var(--color-text-muted); }
.pf-result__signal-note { font-size: 10.5px; color: var(--color-text-muted); font-style: italic; }

/* =========================================================================
   COMPLETED — cards (badges)
   ========================================================================= */
.pf-card,
.workspace .pf-card { padding: 30px var(--sp-xl) 28px; }
.pf-card__head {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: var(--sp-md);
  flex-wrap: wrap;
  text-align: center;
}
.pf-card__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 18px;
  color: var(--color-navy);
  margin: 0;
}
.pf-card__count {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 12px;
  color: var(--color-gold);
  white-space: nowrap;
}
.pf-card__hint {
  font-size: 14px;
  color: var(--color-text-secondary);
  margin: 6px 0 19px;
  text-align: center;
}
.pf-badges { display: flex; flex-wrap: wrap; column-gap: var(--sp-sm); row-gap: 14px; justify-content: center; }
.pf-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  margin: 0 !important;
  background: var(--color-surface);
  border: 2px solid var(--color-gold);
  border-radius: var(--radius-pill);
  cursor: pointer;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 14.5px;
  color: var(--color-navy);
  transition: all var(--duration-fast) var(--ease-out);
}
/* D-651 (S235 FIXER-SHADOWS-3, 24/09/26): the gold rest shadow, scoped to the clickable <button>
   picker only. The bare .pf-badge class is shared with the non-clickable readonly summary badge
   (questionnaire-system.php:2959, <div class="pf-badge is-sel"> inside .pf-badges--readonly), so
   the shadow does not go on the shared rule above. */
button.pf-badge {
  box-shadow: var(--shadow-gold-hover);
}
/* Scoped #buddypress .workspace (matches the .pf-scale__opt/.pf-chip/.pf-yesno__opt pattern
   right above, S222): a bare button.pf-badge:active is specificity (0,2,1), which LOSES to
   Seeko's site-wide button:not([disabled]):not(.disabled):active at (0,3,1) - confirmed live,
   the background painted grey #eee not cream-hover. #buddypress adds an id, so (1,3,1) wins. */
#buddypress .workspace button.pf-badge:active {
  background: var(--color-cream-hover);
  box-shadow: none;
}
/* S227 item 141, Rob: the Reserved (monocle) glyph "is massive compared to the other two and
   it makes the whole pill much taller ... same ratio". Two of the six archetype glyphs are
   emitted at a hardcoded size (gentleman 28x35, scales 34x34, questionnaire-system.php 2410 and
   2397) while the rest arrive 22x22. Normalising the slot to 22px tall with the aspect kept
   fixes both without touching the drawings. MEASURED: Reserved pill 63.00 -> 50.00, level with
   Adventurer and Socialiser at every width. */
.pf-badge__emoji { font-size: 18px; line-height: 1; }
/* S245 row 60 (Rob, the 7th of October 2026: "the labels are slightly low and to the right"). MEASURED LIVE on example_aaron_fitzgerald's Preferences page: every pill is an inline-flex row of
   two items, this icon slot and the label, with an 8px gap between them (.pf-badge above). The slot is EMPTY for these badges (the markup prints nothing into it), a 0 by 0 flex item, but the
   gap is still taken, so the pair is 8px wider than the label alone and justify-content centring puts the label 4px right of the pill's centre: label ink 4.19px, 3.87px, 4.63px and
   4.19px right of centre (the four pills, scale 8), 3.5px in whole pixels at 100 per cent (25 columns clear on the left, 18 on the right). An empty slot is taken out of the row, so the label is
   the only item and sits on the centre. A slot that holds an icon (the wizard result card's archetype glyph) is not empty and is untouched. Vertical: the label ink is 0.28px low in the pill
   at scale 8 and level (15 rows above, 15 below) at 100 per cent, inside the 0.5px limit, so nothing is changed there. */
.pf-badge__emoji:empty { display: none; }
.pf-badge__emoji svg { height: 22px; width: auto; }
.pf-badge:hover { border-color: var(--color-gold); transform: translateY(-1px); }
.pf-badge.is-sel {
  background: #EAF4EC;
  border-color: #2F7D4F;
  color: #2F6B47;
}
.pf-badge.is-locked { opacity: 0.45; cursor: not-allowed; }
.pf-badge.is-locked:hover { border-color: var(--color-gold); transform: none; }

/* =========================================================================
   COMPLETED — section grid
   ========================================================================= */
/* S215 (DASH-30): every other block on the completed Preferences page is centred, and the
   standing rule is that if in doubt it is centred. The gap below keeps the heading and the
   count apart, and flex-wrap still lets them stack at narrow widths. */
.pf-section-label {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: var(--sp-md);
  margin-bottom: var(--sp-md);
  flex-wrap: wrap;
}
.pf-section-label h3 {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 18px;
  color: var(--color-navy);
  margin: 0;
}
.pf-section-label span {
  font-size: 13px;
  font-weight: 600;
  color: var(--color-navy);
}
.pf-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-md);
}
/* 10th tile alone on row 4 — sit in the centre column */
.pf-tile:last-child:nth-child(3n + 1) {
  grid-column: 2 / 3;
}
.pf-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  padding: var(--sp-lg);
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  cursor: pointer;
  text-align: center;
  /* D-651 (S235 FIXER-SHADOWS-3, 24/09/26): the gold rest shadow - was hover-only below. */
  box-shadow: var(--shadow-gold-hover);
  transition: transform var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out);
}
.pf-tile:hover {
  border-color: var(--color-gold);
  transform: translateY(-2px);
  box-shadow: var(--shadow-gold-hover);
}
.pf-tile:active {
  background: var(--color-cream-hover, #FFF5CC);
  box-shadow: none;
}
.pf-tile__check {
  position: absolute;
  top: var(--sp-md);
  right: var(--sp-md);
  width: 24px; height: 24px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--color-success-bg);
  color: var(--color-success);
}
.pf-tile__icon { font-size: 26px; line-height: 1; margin-bottom: 2px; color: var(--color-gold); }
.pf-tile__title {
  margin-top: auto;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 14.5px;
  color: var(--color-navy);
  padding-right: 0;
  line-height: 1.2;
}
.pf-tile__meta {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12.5px;
  color: var(--color-text-muted);
}
.pf-tile__lock {
  display: inline-grid; place-items: center;
  color: var(--color-navy);
}
.pf-tile__edit {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: auto;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 12.5px;
  color: var(--color-gold);
}

/* =========================================================================
   COMPLETED — host opt-in
   ========================================================================= */
.pf-host {
  position: relative;
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  padding: var(--sp-lg) var(--sp-xl) var(--sp-xl);
  text-align: center;
}
.pf-host__ribbon {
  display: inline-block;
  margin-bottom: var(--sp-sm);
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-gold);
}
.pf-host__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 24px;
  color: var(--color-navy);
  margin: 15px 0 var(--sp-md);
}
.pf-host__body {
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--color-navy);
  max-width: 90%;
  margin: 0 auto var(--sp-md);
  text-wrap: pretty;
}
.pf-host__note {
  font-size: 13px;
  font-style: italic;
  color: var(--color-text-muted);
  max-width: 90%;
  margin: 0 auto var(--sp-xl);
}
.pf-host__actions {
  display: flex;
  justify-content: center;
  gap: var(--sp-md);
  flex-wrap: wrap;
}
/* HostOptIn — danger ghost for "No thanks" */
/* Design body values verbatim, but specificity + !important raised to defeat the
   live §42.8.1 rule `#buddypress .workspace .btn.btn--ghost` (1,3,0, !important)
   which otherwise paints this danger button navy. border-color added on hover so
   the competitor's hover-navy border can't bleed through. */
/* S215 (DASH-23): #C0392B is a fifth red that appears nowhere in the brand guide. The guide
   already carries --color-error #C41C1C and that is what the platform's error state uses.
   S217 (Rob 09/09/26): the solid red hover fill read as a red block rather than a control, so
   the hover is an 8 percent wash of that same error red and the red border and red label are
   kept, which is how every other outlined control on the platform behaves. */
#buddypress .workspace .btn.btn--ghost.btn--ghost-danger {
  border-color: var(--color-error, #C41C1C) !important;
  color: var(--color-error, #C41C1C) !important;
}
#buddypress .workspace .btn.btn--ghost.btn--ghost-danger:hover {
  background: rgba(196, 28, 28, 0.08) !important;
  color: var(--color-error, #C41C1C) !important;
  border-color: var(--color-error, #C41C1C) !important;
}
.pf-host__result {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}
.pf-host__result > span {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 20px;
  border-radius: 10px;
  font-weight: 700;
  font-size: 14px;
}
.pf-host__result--yes > span { background: #EAF4EC; color: #2F6B47; border: 1.5px solid #2F7D4F; }
/* S215 (DASH-23): the tint is re-mixed from the brand error red so it matches its own text. */
.pf-host__result--no > span { background: rgba(196, 28, 28, 0.06); color: var(--color-error, #C41C1C); border: 1.5px solid rgba(196, 28, 28, 0.45); }
.pf-host__change {
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-pill);
  cursor: pointer;
  font-family: var(--font-heading);
  font-size: 13px;
  font-weight: 700;
  color: var(--color-navy);
  text-decoration: none;
  padding: 8px 18px;
  transition: all var(--duration-fast) var(--ease-out);
}
/* S215 (DASH-23): a white control with a gold border takes darker cream on hover, not a gold fill. */
.pf-host__change:hover {
  background: var(--color-cream-hover, #FFF5CC);
  color: var(--color-navy);
  border-color: var(--color-gold);
}

/* =========================================================================
   COMPLETED — edit-all CTA
   ========================================================================= */
.pf-editall { display: flex; justify-content: center; padding-top: var(--sp-sm); }
.pf-btn-next--lg { padding: 14px 34px; font-size: 15px; }

/* =========================================================================
   RESPONSIVE — container queries on the viewport frame
   ========================================================================= */
@container vp (max-width: 600px) {
  .pf-sec-head__title { font-size: 25px; }
  .pf-qcard { padding: var(--sp-lg); text-align: center; }
  .pf-qcard__text { font-size: 18px; }
  .pf-chips { justify-content: center; }
  .pf-options { align-items: center; }
  .pf-opt { width: 100%; justify-content: center; }

  /* Scale 1–5 → two-row wrap so labels stay legible on phone */
  .pf-scale { flex-wrap: wrap; justify-content: center; }
  .pf-scale__opt { flex: 0 1 calc(33.33% - 6px); }

  /* Yes/No stays side-by-side; result band stacks */
  .pf-result { flex-direction: column; text-align: center; align-items: center; gap: 0; }
  .pf-result__body { align-items: center; }
  .pf-result__signal {
    align-items: center;
    padding-left: 0;
    padding-top: calc(var(--sp-sm) + 5px);
    border-left: 0;
    border-top: 0;
    width: 100%;
  }
  .pf-hero__top { text-align: center; }

  .pf-grid { grid-template-columns: 1fr 1fr; }
  .pf-tile:last-child:nth-child(3n + 1) { grid-column: auto; }
  .pf-tile__title { font-size: 13px; }

  .pf-nav { flex-wrap: wrap; }
  .pf-nav__right { gap: 2px; }
  .pf-nav__right .btn--subtle { padding: 8px 4px; margin-right: 5px; }
  .pf-btn-next { flex: 1; justify-content: center; }
}

@container vp (max-width: 380px) {
  .pf-grid { grid-template-columns: 1fr; }
  .pf-tile:last-child:nth-child(3n + 1) { grid-column: auto; }
  .pf-scale__opt { flex: 0 1 calc(50% - 4px); }
}
/* end of 45 */

/* ============================================================================
   46. SECTION: Dashboard port (design-agent verbatim)
   Source: uksocials-club/project/dashboard.css from design bundle
   xbccZFwBA7yz7IncSvek-A, ported S103 2026-06-05.
   Workspace content only. Chrome (top bar/navbar/banner/sidenav) is
   wired elsewhere and not affected by this section.
   ============================================================================ */

/* =========================================================================
   Dashboard — page-specific styles
   Tokens and chrome from styles.css; nothing here overrides those.
   ========================================================================= */

/* ── Centred body column ──────────────────────────────────────────────────── */
/* Constrains all dashboard content to ~60% of a wide workspace and centres
   it. At narrow viewports it fills naturally. */
.dash-body {
  max-width: 860px;
  margin: 0 auto;
  width: 100%;
}

/* ── Welcome heading ──────────────────────────────────────────────────────── */
/* S227 item 136, Rob: "reduce the gap above the title and then slightly tighten up the other
   two gaps below it and make sure those two are uniform." MEASURED at 390: the gap above the
   heading was 60.00px and the gap below it 38.00px against the pill-to-card gap of 36.00px.
   padding-top goes, which takes the gap above to 44.00px, and margin-bottom drops to --sp-2xl
   so it matches .dash-section__title-row below at 32.00px. */
.dashboard-welcome {
  margin-bottom: var(--sp-2xl);
  padding-top: 0;
}
/* F-061 (S234, 21/09/2026). The note above states the gap ABOVE this heading as 44.00px, and at
   390 it is exactly that - but the 44px comes from the sidenav scroll cue that sits above the
   workspace while the sidenav is a horizontal strip, not from this rule. MEASURED on the live
   dashboard, nearest painted element above the h1: 44.00px at 390, 36.00px at 768 and at 1024,
   and 0.00px at 1280, where the cover banner ends exactly on the heading. At the two-column
   widths the cue is not rendered, so nothing supplies the gap at all. The container query is the
   same idiom 42.15 uses for this shell and fires on the grid span rather than the screen, which
   is what makes it match the layout that loses the cue. */
@container vp (min-width: 1024px) {
  .dashboard-welcome { padding-top: 44px; }
}

/* ── Section blocks ───────────────────────────────────────────────────────── */
.dash-section {
  /* S207 04/09/26, Rob, on the gap between the Randomise button and the
     "From Your List" pill: "reduce it by a third". 54px -> 36px. This is the
     only rule that sets that gap; nothing else targets .dashboard-section-a/b. */
  margin-bottom: 36px;
  /* 06/09/26, Rob changed the ask: "Make the gap uniform. So the gap between the calendar and
     the 'from your list' pill and between 'from your list' pill and randomise should be the
     same." 36px is now the single spacing value for the section gap, the title row and the CTA
     row, so all three gaps in that column match. */
}
.dash-section__title {
  font-family: var(--font-heading);
  font-size: 18px;
  font-weight: 700;
  color: var(--color-navy);
  letter-spacing: 0.01em;
  margin: 0 0 var(--sp-xl);
  display: inline-block;
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-pill);
  padding: 6.75px 24px 5.25px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.12), var(--shadow-sm);
}
/* S227 item 136: 36px -> --sp-2xl 32px, so the pill-to-card gap matches the heading-to-pill
   gap above it, which is what he asked to be uniform. NOTE for Rob: this leaves the section gap
   and the Randomise gap (both .dash-section / .dash-section__cta) at 36px. */
.dash-section__title-row {
  text-align: center;
  margin-bottom: var(--sp-2xl);
}
.dash-section__title-row .dash-section__title {
  margin-bottom: 0;
}
#list-heading {
  font-size: 21px;
}
.dash-section__cta {
  display: flex;
  justify-content: center;
  margin-top: 36px;      /* S207 06/09/26: uniform with the section gap */
}

/* ── Event rows ───────────────────────────────────────────────────────────── */
.event-list {
  display: flex;
  flex-direction: column;
  max-width: 700px;
  margin: 0 auto;
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}

.event-row {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: var(--sp-lg);
  padding: 14px var(--sp-xl);
  background: var(--color-surface);
  border: none;
  /* S227 item 135, Rob: "it looks like the borders between each of those events on this card
     is grey. Is that gold, it should be gold?" It WAS gold, at 18% over white, which reads grey.
     Full strength, the same var(--color-gold) as the card's own 1.5px edge. */
  border-bottom: 1px solid var(--color-gold);
  transition: background var(--duration-fast) var(--ease-out);
  cursor: pointer;
  text-decoration: none;
}
.event-row:last-child { border-bottom: none; }
.event-row:hover { background: var(--color-cream); }

.event-row__date {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 13px;
  color: var(--color-gold);
  white-space: nowrap;
  /* S217 09/09/2026: D-502 put the date into house style ("28th of October 2026") and 108px no
     longer holds it: the chip overflowed by 21 to 42px into the row divider. The widest string
     the format can produce, measured live in this chip, is "22nd of September 2026" at 150px. */
  width: 152px;
  text-align: right;
  flex-shrink: 0;
}
/* F-061 (S234, 21/09/2026). The S233 amendment for the dashboard feed asks for this divider at
   full alpha; it measured rgba(204,153,0,0.35). This class is only ever emitted by
   profile-system.php alongside .dashboard-feed-divider, on the feed rows and nowhere else, so the
   base rule is the source and there is no second surface to protect. */
.event-row__sep {
  display: block;
  width: 1px;
  height: 30px;
  background: var(--color-gold, #CC9900);
  flex-shrink: 0;
}
/* S227 item 135, Rob: "what are those tick boxes? Why are they on grey squares? ... they need
   to have a gold border." They are the no-image placeholder (profile-system.php 6431). White
   with a gold edge, like every other panel on the platform; border-box keeps 40x40 and 32x32. */
.event-row__thumb {
  width: 40px;
  height: 40px;
  border-radius: 6px;
  background: var(--color-surface);
  border: 1px solid var(--color-gold);
  display: grid;
  place-items: center;
  font-size: 20px;
  line-height: 1;
  font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;
  flex-shrink: 0;
  font-variant-emoji: emoji;
}
/* The calendar fallback's painted mass reads low inside its otherwise centred 24px SVG
   canvas. Lift only that fallback glyph; real event thumbnails and every other glyph keep
   the shared event-row geometry unchanged. */
.event-row__thumb.dashboard-feed-thumb-emoji > .uks-glyph--calendar {
  display: block;
  transform: translateY(-1px);
}
.event-row__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 15px;
  color: var(--color-navy);
  text-decoration: none;
  text-wrap: pretty;
  flex: 0 0 auto;
}
.event-row:hover .event-row__title { text-decoration: underline; }

/* ── Empty state ──────────────────────────────────────────────────────────── */
.event-empty {
  text-align: center;
  color: var(--color-text-secondary);
  font-size: 15px;
  /* R3-12: the parent theme's paragraph margin (24px) hung below the last feed section. */
  margin: 0;
  padding: 17px var(--sp-xl) var(--sp-2xl);
  text-wrap: pretty;
  line-height: 1.6;
}
.event-empty a {
  color: var(--color-gold);
  font-weight: 600;
  text-decoration: underline;
}
.event-empty a:hover { color: var(--color-gold); }

/* ── Controls row (calendar + week nav side by side) ─────────────────────── */
.dash-controls {
  display: flex;
  align-items: center;
  gap: var(--sp-3xl);
  justify-content: center;
  margin-bottom: var(--sp-xl);
  flex-wrap: wrap;
}

/* ── Mini calendar widget ─────────────────────────────────────────────────── */
.cal {
  background: var(--color-surface);
  border: 2px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: var(--sp-lg) var(--sp-md) var(--sp-md);
  min-width: 226px;
  box-shadow: var(--shadow-sm);
}

.cal__hd {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--sp-sm);
  gap: var(--sp-sm);
}
.cal__mo {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 14px;
  color: var(--color-navy);
  letter-spacing: 0.01em;
}
.cal__nav-btn {
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--color-cream);
  border: 1.5px solid var(--color-gold);
  border-radius: 10px; /* S234 21/09/26, D-508: was 8px. */
  font-size: 0;
  color: var(--color-navy);
  cursor: pointer;
  line-height: 1;
  padding: 0;
  box-shadow: var(--shadow-gold-hover); /* R3-11 24/09/26, D-640: gold at rest wherever the border is gold. */
  transition: all var(--duration-fast) var(--ease-out);
}
/* R3-11 24/09/26: gated so a tap on a phone cannot leave the chevron painted dark cream after
   release (same fix as S224 item 64 on .btn--primary). :active below paints the press itself. */
@media (hover: hover) {
.cal__nav-btn:hover {
  background: var(--color-cream-hover);
  border-color: var(--color-gold);
}
}
/* R3-11 25/09/26 (D-640): !important added to both properties, and border-color asserted
   for the first time here. Traced live while genuinely held (tools/s235_r3_11_trace_active.js,
   CDP-level mouse.down so :active really fires): the parent theme's own reset in
   custom_styles/seeko-dynamic.css - button:not([disabled]):not(.disabled):active - carries
   three pseudo/attribute clauses plus the element (specificity 0,3,1), which beats this rule's
   two classes (0,2,0) on raw CSS specificity alone, !important and source order aside. It was
   painting rgb(238, 238, 238) (browser grey) with a transparent border - the press Rob reported
   as never gold. .week-nav__btn:active further down this file already carries !important for
   exactly this reason and was never affected; this rule now matches that idiom. */
.cal__nav-btn:active {
  background: var(--color-cream-hover) !important;
  border-color: var(--color-gold) !important;
  box-shadow: none !important;
}
.cal__nav-btn svg {
  display: block;
  width: 16px;
  height: 16px;
  overflow: visible;
}
/* R3-11 24/09/26 (D-640, Rob: "never centred by ink"): translateX(-1.5px)/(1.5px) removed.
   Measured at dpr 8 (gold ring 50 percent coverage bounds vs navy chevron ink bounds,
   results/s235/r3-11/ink_before.json): WITH this transform prev read -1.5003px and next
   read +1.4996px offset (ink centre minus circle centre), matching the transform value
   pixel for pixel - the ink was already dead centre in the untransformed box and the
   transform was the entire fault. Removing it reads 0.0003px / 0.0004px at 360 and 1280,
   confirmed in results/s235/r3-11/ink_after.json. */

/* 7-column grid — dashboard defaults are fixed; embedded profile calendars
   supply the same geometry through scoped custom properties as they resize. */
/* S245 row 99, second pass (Rob, the 8th of October 2026: "the circle on the 15th looks like it is slightly right of centre, or is the number slightly left?").
   MEASURED on the live dashboard as example_aaron_fitzgerald, every one of the 31 day cells with the real pointer on it, the painted ink of the digits against the painted circle (the
   connected components of one screenshot per cell, ink midpoint minus circle midpoint), with the proportional digits of 46.CAL2 below already live: at 360 the chosen 15th read 0.563px
   LEFT of its circle's centre and 23 of the 31 days read more than 0.5px off at dpr 8 (11 of 31, the 15th 0.5px, at dpr 2); from 768 up the 15th read +0.188px and no day more than 0.375px.
   CAUSE: the page puts this grid on a fractional pixel, a different one at each width (x.3125 from 768 up, x.5 at 360, where the grid and every cell sit on 61.5 plus 32 a column).
   Chromium paints a box (the circle is the cell's own border) on whole pixels from the nearest paint origin, but lays the digits (text) out at the fractional position, so at x.5 the circle
   moves half a pixel one way and the digits do not. A stylesheet cannot read where the page puts the grid, so the fraction cannot be removed at its source.
   FIX: the grid takes a transform that is not a plain translation. Chromium then gives the grid its own paint origin, and the circle and the digits are painted from the same pixel grid
   whatever the page offset. Measured live by injecting this one declaration, at dpr 8, the same at 1920, 1280, 1024, 768 and 360: every day between -0.375 and +0.375px (mean -0.101px,
   the 15th -0.063px), and at dpr 2 no day more than 0.5px. 0.001deg moves the far corner of the 222px grid by 0.004px, which is nothing the eye can see.
   TRIED LIVE AND NOT USED: translate(), translateZ(0), contain: layout, isolation and a plain stacking context change nothing; will-change: transform works but takes the LCD colour
   fringing off the digits; contain: paint works but would clip the drop shadow of the today cell (--shadow-gold-hover) at the grid's edge. This rule also serves the embedded profile calendars. */
.cal__grid {
  display: grid;
  grid-template-columns: repeat(7, var(--cal-cell-size, 30px));
  gap: var(--cal-cell-gap, 2px);
  justify-content: center;
  transform: rotate(0.001deg);
}
.cal__day-label {
  width: var(--cal-cell-size, 30px);
  height: var(--cal-label-height, 20px);
  display: grid;
  place-items: center;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: var(--cal-label-font-size, 11px);
  color: var(--color-gold);
}
/* 46.CAL1 THE DAY CELL, AND THE ONE RULE THAT OWNS ITS GEOMETRY (S221, 14/09/26).
   Lettered like 46.X / 46.Y / 46.Z above, inside "46. SECTION: Dashboard port", where this block
   lives. The two comments replaced here called themselves 47.3 and 47.4, which are the GALLERY's
   own 47.3 and 47.4 further down this file: a duplicate number nobody could have found by reading
   (LB-382). No new section number is claimed.

   Rob, 14/09/26: "the circles on the calendar have been rendered low they're too low they're like
   a pixel or two too low. We've fixed this so many times. Check the CSS rules on those badges and
   make sure there's only one rule and it centers it perfectly."

   MEASURED BEFORE THE CHANGE. The whole grid was photographed ONCE at deviceScaleFactor 8 and each
   day's INK measured against the PAINTED ring at 50 percent coverage, never box against box: the
   ring sat 1.3125px BELOW the number's ink centre, identically on today, on a going ring and on a
   selected day. At dpr 2 it read 1.25px and at dpr 1 1.5px, so it was visible at the scale Rob was
   actually looking at.

   WHY IT WAS LOW: six rules were positioning one element and they fought each other.
     1. this rule carried `padding: 2px 0 0`, which pushed the centred number 1px DOWN in a
        border-box cell;
     2. a SECOND `.cal__cell` rule further down this same file re-declared that padding with
        !important, so editing this one alone changed nothing (the S190 note said so);
     3. `.cal__cell { transform: translate(0, 0.5px) }` moved the whole cell, ring included, DOWN;
     4. `.cal__cell-num { transform: translate(0, -0.5px) }` moved the number back UP by exactly
        the same amount, so the pair existed only to leave the ring half a pixel below the number;
     5. `.cal__cell--today` and `.cal__cell--sel` each added `position: relative; left: -1px`, so
        two states sat a pixel left of every other day and of the weekday label above them;
     6. the box was 30 wide and 29 tall, so `border-radius: 50%` drew an ELLIPSE, not a circle.

   WHAT THIS RULE DOES. It is the only rule that sets this cell's box. The box is square, so the
   mark is a true circle; the padding is zero, so nothing pushes the number off centre; and the
   number is centred on both axes by flex with `line-height: 1`, which puts its line box on the
   geometric centre. The state rules below change colour, background and border colour ONLY: no
   state moves anything, and nothing else in this file may set width, height, padding, margin,
   min-height, display, line-height or transform on `.cal__cell` again.

   PARITY (LB-335). 30 is EVEN, so the centre line falls between two pixels rather than on one:
   15.000px from the top edge. That is deliberate and it costs nothing here, because the number is
   no longer placed by padding (which quantises to whole pixels, which is what stalled S190 and
   S198) but by a transform on its own span, which is composited and lands on the device grid. The
   ring's border is specified 1.5px and Chromium floors the USED value to 1px; a border is
   symmetric, so the ring's painted centre is the box centre either way and the stroke's own parity
   never enters the sum.

   MEASURED AFTER: 0.0625px at dpr 8, 0.125px at dpr 4, 0.25px at dpr 2 and 0.5px at dpr 1, which
   is the raster floor at each of those scales and cannot be beaten by any CSS value. */
.cal__cell {
  box-sizing: border-box;
  width: var(--cal-cell-size, 30px);
  height: var(--cal-cell-size, 30px);
  min-height: 0 !important;
  padding: 0 !important;
  margin: 0 !important;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: var(--cal-cell-font-size, 12px);
  color: var(--color-navy);
  background: transparent;
  border: 1.5px solid transparent;
  border-radius: 50%;
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out);
}
/* 46.CAL2 The day number: the ONE sub-pixel correction, and the only other declaration anywhere that
   touches where the number sits. A digit's ink is not centred in its own line box, because a
   font's ascent and descent are not symmetric about the cap height; at this size the ink sits
   0.3125px ABOVE the line box centre. Measured, then bracketed on the live page: a nudge of 0 read
   -0.3125px, 0.25 read -0.0625px and 0.3125 read +0.0625px. 0.25px is taken because it is also a
   whole number of device pixels at every scale the site is viewed at (2 at dpr 8, 1 at dpr 4, a
   half at dpr 2), so the value is not itself rounded on the way to the screen.
   TRANSFORM AND NOT PADDING: padding quantises to whole pixels here, which is what stalled S190 at
   0.38px and S198 at 0.237px; a transform is composited and does not. */
/* S245 row 99 (Rob, the 8th of October 2026: "the circle on the 15th looks like it is slightly right of centre, or is the number slightly left? ... it needs overlays and properly measuring").
   MEASURED by the painted pixels at deviceScaleFactor 8 (the ring and the digits are the connected components of one screenshot of each cell: the ring the one that spans the cell, the digits
   the ones inside; the midpoints of the two compared on both axes), on the real dashboard as example_aaron_fitzgerald, all 31 day cells with the real pointer on each (the hover state paints
   the same green ring and green digits as the chosen day), at 1920, 1440, 1280, 1024, 768 and 600: VERTICALLY the digits sit within 0.063px of the ring centre on every day (the 0.25px nudge
   above is right and is left alone); HORIZONTALLY the digits' ink midpoint ran from 0.563px LEFT of the ring's midpoint (the 21st) to 0.688px RIGHT of it (the 14th), the chosen 15th 0.625px
   right, mean +0.258px, 6 of the 31 days over the 0.5px a centred label may differ by. CAUSE: the font's DEFAULT digits are tabular, so every digit has the same advance and the ones
   (1) carry about a pixel of empty room on one side; flex centring centres the ADVANCE BOX, so a number starting with 1 had its ink pushed right of the ring's centre and a number ending in 1
   pushed left (10 to 19 read +0.5 to +0.69, 21 and 31 read -0.56 and -0.44), which is why only some days looked off. The fix is the font's own proportional digits, which give every digit an
   advance that hugs its ink, so the box that flex centres is the ink: the number box of the 15th went from 13.36px to 12.02px wide, the spread of all 31 days from -0.56..+0.69 to
   -0.06..+0.38 (max 0.375), the same at every width above. NOT a nudge: a fixed translate would centre some numbers and push others out (a uniform -0.26px made 21 and 31 worse).
   AT 360 the calendar's left edge falls on a half pixel (the cells at x.5): the ring, a box border, is painted on whole pixels (measured: layout 620.31 painted at 620.00, 620.56 at 621.00,
   a one-pixel sawtooth against the digits, which follow layout), so there every day reads about 0.5px left of its ring whatever its shape; proportional digits cut the worst day there from
   1.31px to 0.88px (mean -0.57 to -0.60); the half pixel itself is taken out by the transform on .cal__grid above (S245 row 99, second pass). */
.cal__cell-num {
  display: block;
  font-variant-numeric: proportional-nums;
  transform: translate(0px, 0.25px);
}
.cal__cell--blank {
  visibility: hidden;
  pointer-events: none;
  cursor: default;
}
.cal__cell:hover:not(.cal__cell--today):not(.cal__cell--sel) {
  background: var(--color-surface-raised);
  border-color: var(--color-border-strong);
}
.cal__cell--today {
  background: var(--color-cream);
  border-color: var(--color-gold);
}
.cal__cell--sel {
  background: var(--color-success-bg);
  border-color: var(--color-success);
  color: var(--color-success);
  font-weight: 700;
}
/* today + selected */
.cal__cell--today.cal__cell--sel {
  background: var(--color-success-bg);
  border-color: var(--color-success);
  color: var(--color-success);
}
/* S181 (18/08/26, Rob): a GREEN CIRCLE on every date the member actually has an event they are
   going to - "No point having a calendar that isn't marked with the dates you actually have
   events." Ring, not fill, so today/selected states still read through it.

   S190 (VS4 task 29): the :focus and :hover selectors are NOT decoration - without them the ring
   was DESTROYED the moment the cell took focus, and it was driven, not theorised. The day cells are
   <button>s, and Seeko's parent theme carries
     button:focus { box-shadow: rgba(0,0,0,.5) 0 0 0 0 }   (seeko-dynamic.css)
   box-shadow is a single property, so the parent rule REPLACED this ring wholesale, and `button:focus`
   (0-1-1) outranks a bare `.cal__cell--going` (0-1-0). Three Tab presses from a selected cell put the
   member on the day they hold a place for and the green circle simply vanished - with nothing in its
   place, because that parent shadow has zero spread and paints nothing. CLICKING the day hid the bug,
   because .cal__cell--sel then drew its own green border; only the keyboard path brought it to light.
   Listing the states on this rule keeps the repair where the ring is defined rather than stacking a
   scope-bump somewhere else, and 0-2-0 (class plus pseudo-class) beats the parent rule at 0-1-1 with no !important. */
/* 🔴 S190 SECOND PASS (Rob, same day, looking at all three marks side by side): "all three
   circles are different sizes lol. The 24 gold and cream is correct so make that global."
   Measured by ink before changing anything: today 30x28, the going ring 28x26, the focus ring
   38x36. They could never have matched, because they were three DIFFERENT mechanisms - today is
   a BORDER on the border box, the going ring was an INSET box-shadow which starts inside the
   border and is therefore smaller, and focus is an OUTLINE which sits outside the border box by
   its offset and is therefore bigger.
   So the going ring now uses the SAME mechanism as the today marker - the cell's own 1.5px
   border - which makes it the same 30x28 circle by construction rather than by a matched number
   that would drift the moment the cell resized.
   ⚠️ IT IS STILL A BORDER-COLOUR AND NOT A box-shadow FOR THE S190 FIRST-PASS REASON: the parent
   theme's `button:focus` box-shadow replaced the old inset ring outright and left nothing behind.
   A border is untouched by that rule, so the ring now survives focus by construction too, which
   is a stronger guarantee than the selector list it replaces.
   ⚠️ ON A DAY THAT IS BOTH TODAY AND GOING the green wins the ring and today keeps its cream
   fill, so both states still read. That is a deliberate choice: the cream already says "today",
   while the green circle is the only thing that says "you have somewhere to be". */
.cal__cell--going,
.cal__cell--going:focus,
.cal__cell--going:hover,
.cal__cell--going.cal__cell--sel,
.cal__cell--going.cal__cell--sel:focus {
  border-color: var(--color-success);
  border-radius: 50%;
}
/* S182 (T-S181-006): the "You're going" LIST is removed (Rob 18/08/26 - the green ring is the
   signal). Its D-389 toggle is rehomed onto the day-click GOING row below, which also carries
   the ticket code starred behind an eye (the password-hider pattern). .going-code is shared
   with the event-page aside card. */
.event-row--going {
  border-color: var(--color-success);
  align-items: flex-start;
}
.event-row--going .event-row__body {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.event-row--going .event-row__title { text-decoration: none; }
.event-row__going-line {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}
.event-row__going-badge {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--color-success);
  background: var(--color-success-bg);
  border: 1px solid var(--color-success);
  border-radius: 999px;
  padding: 2px 10px;
  white-space: nowrap;
}
.event-row--going-hidden .event-row__title,
.event-row--going-hidden .dashboard-feed-date { opacity: 0.55; }
.going-vis { font-size: 11px; padding: 3px 8px; white-space: nowrap; }
.going-code {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}
/* S229 16/09/26 (T-S229-053), Rob: "the box the I is in is still a little bit taller than the
   code box. They should be the same height and they should be perfectly level. And the label
   code is just definitely too high." MEASURED at dpr 8 on the event page at 360 from painted
   rows: the eye's box painted 437.125 to 463.000 and the code box 446.375 to 454.000, so the
   code box was 7.6px shorter; the label's ink centred 449.062 against the row's 450.141, so
   1.08px high. After: both boxes paint 437.125 to 463.000 and all three centre on 450.062. */
.going-code__label {
  position: relative;
  top: 1px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--color-gold-dark);
}
/* S227 item 82, Rob: "the box itself should be white background gold border". */
.going-code__value {
  display: inline-flex;
  align-items: center;
  height: 26px;
  font-size: 12px;
  color: var(--color-navy);
  background: var(--color-surface);
  border: 1px solid var(--color-gold);
  border-radius: 6px;
  padding: 0 8px;
  letter-spacing: .08em;
}
.going-code__eye {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  margin: 0;
  /* S227 item 82, Rob: "the eye icon is not on brand ... blue iris, gold eyelids". The SVG's
     <path> is the eyelid outline and its <circle> is the iris, so the two are painted apart
     here rather than both inheriting one currentColor. */
  border: 1px solid var(--color-gold);
  border-radius: 6px;
  background: var(--color-surface);
  color: var(--color-navy);
  cursor: pointer;
}
.going-code__eye svg path { stroke: var(--color-gold); }
.going-code__eye svg circle { stroke: var(--color-navy); fill: var(--color-navy); }
.going-code__eye:hover { border-color: var(--color-gold); color: var(--color-gold-dark); }
.going-code__eye[aria-pressed="true"] { background: var(--color-cream); border-color: var(--color-gold); }

/* ── Week navigation ──────────────────────────────────────────────────────── */
.week-nav {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-md);
}

/* Top row: both buttons side by side */
.week-nav__btns {
  display: flex;
  gap: var(--sp-md);
}

/* Bottom: label + optional reset link, stacked + centred */
.week-nav__info {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  text-align: center;
}

.week-nav__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: var(--color-cream) !important;
  border: 2px solid var(--color-gold) !important;
  color: var(--color-navy) !important;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 13px;
  padding: 10px 18px;
  line-height: 1;
  border-radius: 10px;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out);
  box-shadow: var(--shadow-gold-hover); /* R3-03 24/09/26, D-640: was a navy shadow; gold at rest wherever the border is gold. */
}
.week-nav__arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}
/* Row 8 (Rob 06/10/26: "Why are they now too low? And it looks like the words are too high"),
   S245 09/10/26. Replaces the S232 / R3-11 (24/09/26, D-640) comment and its translateY(1.5px).
   MEASURED off the painted pixels of the live dashboard (batch-J ink_weeknav.js: the button, the label
   and the arrow each read from a screenshot at dpr 1, 2 and 8, at 1280 and 360, with the row moved
   through a whole pixel of page position): the arrow ink sat +1.50px BELOW the button's painted
   midline at every width, dpr and position. R3-11 had tuned that nudge to the label's x-height
   midline, which is not the button's centre. The arrow is drawn centred in its own 14px box (its
   polyline runs 5 to 19 on a 24 box), so with no nudge its ink midline reads +0.00px against the
   button's at every width, dpr and position tried. The nudge is kept only for the week-nav buttons
   this row does not name (the single event page's series pager), so they are exactly as they were. */
.week-nav__arrow svg {
  display: block;
  width: 14px;
  height: 14px;
  overflow: visible;
}
.week-nav__btn:not(.dashboard-week-nav-btn) .week-nav__arrow svg {
  transform: translateY(1.5px);
}
/* Row 8, the words (same measurement). The label's painted midline read -1.00px or 0.00px against the
   button's at dpr 1, and -0.63px or +0.38px at an emulated dpr 8, depending only on where the row happened to sit
   on the page: the text snaps to a whole pixel from the button's page position and the box does not, so
   the words stepped a pixel whenever the dashboard above them changed height by a fraction. No static
   nudge can fix a value that moves. The button is therefore made its own paint unit (contain: paint),
   which takes the page position out of it: the label then reads the same at every position tried
   (six to twelve fractions of a pixel, both buttons, 1280 and 360, on three accounts). Once it stops moving it needs no nudge:
   it reads 0.00px at dpr 1, +0.13 to +0.38px at an emulated dpr 8 (the emulation snaps text to whole CSS pixels,
   real hardware does not), and -0.08px and -0.13px at a native dpr 6 and 4, all inside the 0.5px rule.
   A lift of 0.25px was tried and dropped: it closed the emulated reading and opened the native one. contain: paint
   only clips what is drawn inside the button, which is the label and the arrow, both inside the padding box;
   the button's own shadow and focus outline are its own decoration and are not clipped. */
.dashboard-week-nav-btn {
  contain: paint;
}
/* R3-03 24/09/26 (D-640): gated so a tap on a phone cannot leave Prev/Next painted dark cream
   after the week reloads (same fix as S224 item 64 on .btn--primary). Also carries the border/
   colour re-assertion that used to be a separate "46.Y" rule further down this file - Seeko's
   button:hover wipes the border on parent-theme buttons, so this still needs !important, but it
   is now the one place that says so (rule of one), not a second rule stacked on top. */
@media (hover: hover) {
.week-nav__btn:hover {
  border: 2px solid var(--color-gold) !important;
  background: var(--color-cream-hover) !important;
  color: var(--color-navy) !important;
  box-shadow: var(--shadow-gold-hover) !important;
}
}
.week-nav__btn:focus {
  border: 2px solid var(--color-gold) !important;
  background: var(--color-cream) !important;
  color: var(--color-navy) !important;
}
/* Pressed and in-flight (D-640): darker cream, no shadow, self-sufficient so a device that never
   matches :hover still gets the momentary press. Resets the instant :active clears or `disabled`
   is removed by the JS below - never sticky. */
.week-nav__btn:active {
  background: var(--color-cream-hover) !important;
  box-shadow: none !important;
}

.week-nav__label {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 14px;
  color: var(--color-navy);
  white-space: nowrap;
}
/* R3-04 (24/09/2026): background is already none/transparent above - measured live via
   Playwright, computed backgroundColor is rgba(0,0,0,0) at rest. The grey Rob saw and
   photographed is Android Chrome's own translucent tap-highlight overlay painting on a real
   touch tap, invisible to any non-touch measurement (same root cause as R3-17/18 on
   .gal-modal/.gal-lightbox buttons, same day, same fix). */
.week-nav__reset {
  background: none;
  border: none;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 12px;
  color: var(--color-gold);
  cursor: pointer;
  padding: 0;
  text-decoration: underline;
  letter-spacing: 0.01em;
  outline: none;
  -webkit-tap-highlight-color: transparent;
}
.week-nav__reset:hover { color: var(--color-gold); }

/* ── Randomise button ───────────────────────────────────────────────────── */
.dash-section__cta .btn {
  line-height: 1;
  box-shadow: 0 2px 0 rgba(3,27,131,0.10), 0 3px 6px rgba(3,27,131,0.10);
}
.dash-section__cta .btn:hover {
  box-shadow: var(--shadow-gold-hover);
}

/* ── Responsive ───────────────────────────────────────────────────────────── */
@container vp (max-width: 720px) {
  .event-row {
    grid-template-columns: auto 1px auto 1fr;
    gap: var(--sp-md);
    padding: 12px var(--sp-lg);
  }
  .event-row__date { text-align: center; }
  .dash-controls { gap: var(--sp-xl); }
}

@container vp (max-width: 500px) {
  .event-row {
    display: grid;
    grid-template-columns: auto auto;
    grid-template-rows: auto auto;
    gap: var(--sp-xs) var(--sp-md);
    padding: var(--sp-md) var(--sp-lg);
    align-items: start;
    justify-content: center;
  }
  .event-row__sep { display: none; }
  .event-row__date {
    grid-column: 1 / -1;
    width: auto;
    text-align: center;
    font-size: 11px;
  }
  .event-row__thumb {
    width: 32px;
    height: 32px;
    font-size: 16px;
    align-self: center;
  }
  .event-row__title { align-self: center; font-size: 14px; flex: unset; }

  .dash-controls { flex-direction: column; gap: var(--sp-xl); }
  .week-nav { gap: var(--sp-sm); }
  .week-nav__mid { min-width: 130px; }
  .week-nav__label { font-size: 13px; white-space: normal; text-align: center; }
}

/* 46.X Seeko parent-theme overrides — defeat universal button margin/padding
   that stretches the calendar grid + button rows. Seeko applies
   `margin-bottom: 18px !important` to every <button>, and BP/Bootstrap apply
   default button padding. Reset on the design's selectors so the spec's
   intended sizing wins. */
/* S221 (14/09/26): `.cal__cell` is NOT in this list any more, and the second `.cal__cell` rule
   that used to follow it (padding 2px 0 0 !important, min-height 0 !important) is gone. Both are
   geometry, and geometry now lives in exactly one place, 47.2, which carries its own
   `margin: 0 !important`, `padding: 0 !important` and `min-height: 0 !important` so it still beats
   Seeko's `button { margin-bottom: 18px !important }` and `button { padding: 0.5rem 1rem }`. The
   two rules below it are unchanged and still reset the other dashboard buttons. */
.cal__nav-btn,
.week-nav__btn,
.week-nav__reset,
.dash-section__cta .btn,
.dashboard-randomise-btn {
  margin: 0 !important;
}
.cal__nav-btn { min-height: 0 !important; }

/* 46.Y Hover border preservation - REMOVED R3-03 24/09/26. This duplicated the rest/hover/focus
   border+background+colour declared at 46.X (both !important, same specificity), and depending
   on load order could win over 46.X's darker-on-hover value, which is most likely why Prev/Next
   read as stuck on rest cream after a real click. Rule of one: 46.X is now the only place this
   is said. */

/* =========================================================================
   §58 Reputation page — verbatim from design reputation.css
   ========================================================================= */

/* ── Workspace width constraint ──────────────────────────────────────────── */
/* .workspace max-width already set in §42.1; this overrides for rep page to
   match design's 760px centred panel exactly. */
body.profile-dashboard-active .workspace[data-screen-label="reputation"],
body.profile-dashboard-active .reputation-workspace {
  max-width: 760px;
  margin-left: auto;
  margin-right: auto;
}

/* ── Subtitle + rule wrapper ─────────────────────────────────────────────── */
.rep-subtitle-wrap {
  display: table;
  margin: 0 auto;
}
.rep-subtitle-wrap .workspace__subtitle {
  display: block;
  margin-bottom: var(--sp-sm);
}

/* ── Header rule ─────────────────────────────────────────────────────────── */
.rep-header-rule {
  width: 100%;
  height: 1.5px;
  background: var(--color-gold);
  border-radius: var(--radius-pill);
  margin-top: var(--sp-sm);
}

/* ── Zero state ──────────────────────────────────────────────────────────── */
.rep-empty {
  text-align: center;
  /* S210 06/09/26: measured, then set. The visible gap above the megaphone was 96px and the gap
     below the hint 88px, because the header above contributes 32px of its own margin and the info
     panel below contributes 24px. Rob asked for the two made uniform and both cut by 20 percent,
     so the target is 74px of visible space each side: 42px of padding on top plus the headers 32,
     and 50px underneath plus the panels 24. The horizontal padding is unchanged. */
  padding: 42px var(--sp-xl) 50px;
  max-width: 520px;
  margin: 0 auto;
}
/* S158 29/07/26 (T594): holds the SVG megaphone now, not the 👄 emoji, so the
   emoji font stack has gone and the colour is the brand gold the SVG inherits
   through `currentColor`. Size comes from the SVG's own width/height attribute. */
.rep-empty__glyph {
  margin-bottom: var(--sp-xl);
  line-height: 1;
  color: var(--color-gold, #CC9900);
}
.rep-empty__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 22px;
  color: var(--color-navy);
  margin-bottom: var(--sp-md);
}
.rep-empty__hint {
  font-size: 15px;
  color: var(--color-text-secondary);
  line-height: 1.65;
  text-wrap: pretty;
}

/* ── Building state ──────────────────────────────────────────────────────── */
.rep-building {
  text-align: center;
  max-width: 480px;
  margin: 0 auto;
  padding: var(--sp-3xl) var(--sp-xl) var(--sp-4xl);
}
/* S158 29/07/26 (T594): same swap as .rep-empty__glyph above. */
.rep-building__icon {
  margin-bottom: var(--sp-xl);
  line-height: 1;
  color: var(--color-gold, #CC9900);
}
.rep-building__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 20px;
  color: var(--color-navy);
  margin-bottom: var(--sp-sm);
}
.rep-building__hint {
  font-size: 15px;
  color: var(--color-text-secondary);
  margin-bottom: var(--sp-2xl);
  text-wrap: pretty;
}
.rep-building__track {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-md);
  margin-bottom: var(--sp-2xl);
}
.rep-building__pips {
  display: flex;
  gap: var(--sp-md);
}
.rep-building__pip {
  width: 56px;
  height: 8px;
  border-radius: var(--radius-pill);
  background: var(--color-surface-sunken);
  border: 1.5px solid var(--color-border-strong);
  transition: background var(--duration-normal) var(--ease-out),
              border-color var(--duration-normal) var(--ease-out);
}
.rep-building__pip--done {
  background: var(--color-gold);
  border-color: var(--color-gold);
}
.rep-building__track-label {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 12px;
  color: var(--color-gold);
  text-transform: uppercase;
  letter-spacing: 0.07em;
}
.rep-building__sub {
  font-size: 14px;
  color: var(--color-text-secondary);
  line-height: 1.65;
  text-wrap: pretty;
  margin: 0;
}

/* ── Score hero ──────────────────────────────────────────────────────────── */
.rep-hero {
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: var(--sp-3xl) var(--sp-2xl);
  text-align: center;
  box-shadow: var(--shadow-sm);
  margin-bottom: var(--sp-xl);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-lg);
}
.rep-hero__score-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-lg);
}
.rep-stars {
  display: flex;
  gap: 8px;
  align-items: center;
}
/* S244 row 121 (Rob 08/10 ~18:5x: "Reputation stars where the star isn't quite filled up, it's got a kinda greyish background. That
   should be the light cream colour."). The empty part of a part-filled star is the second gradient stop, which the star renderer
   (profile-system.php 12436) writes as the attribute stop-color="#E8E5DE", a grey-beige that is not a site colour. A stylesheet rule
   outranks a presentation attribute, so the stop takes the site's light cream: var(--color-cream) #FFFBE6 (BRAND_GUIDE: white, light
   cream and dark cream). The colour is carried by color and read through currentcolor, so the stop's computed color is the value the
   comparison engine measures and stop-color resolves to the same cream. Both pages that print the renderer use this one component. */
.rep-stars stop:last-child { color: var(--color-cream); stop-color: currentcolor; }
.rep-hero__num {
  display: flex;
  align-items: baseline;
  gap: 8px;
  line-height: 1;
}
.rep-hero__num-big {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 64px;
  color: var(--color-navy);
  letter-spacing: -0.03em;
  line-height: 1;
}
.rep-hero__num-denom {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 26px;
  color: var(--color-text-muted);
}
.rep-hero__count {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-gold);
  position: relative;
  z-index: 1;
}

/* ── Sections ────────────────────────────────────────────────────────────── */
.rep-section {
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: var(--sp-2xl);
  box-shadow: var(--shadow-sm);
  margin-bottom: var(--sp-xl);
}
/* S244 row 122 (Rob 08/10 ~18:5x on the Points to work on panel: "that looks gross. Ditch that colour. Just make that a normal panel. But
   make the counter badge with the red colours. That way it kind of looks like a warning but not too much to stress people out."):
   the .rep-section--flags rule that tinted the panel (--color-warning-bg ground, orange border) is removed, so the panel is the normal
   .rep-section above: white, 1.5px gold border, the card radius and shadow. The class stays in the markup (profile-system.php 12573). */
.rep-section__head {
  text-align: center;
  margin-bottom: var(--sp-xl);
}
.rep-section__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 18px;
  color: var(--color-navy);
  margin-bottom: var(--sp-xs);
}
/* S244 row 122: the .rep-section__title--flags orange title colour is removed with the panel tint; the title is the normal navy of
   .rep-section__title (the dashboard h2 rule already forced navy over it, so nothing on screen moves). */
.rep-section__hint {
  font-size: 14px;
  color: var(--color-text-secondary);
}

/* ── Positive badges ─────────────────────────────────────────────────────── */
.rep-badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-md);
  justify-content: center;
  max-width: 640px;
  margin: 0 auto;
}
.rep-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-sm);
  background: var(--color-surface);
  color: var(--color-navy);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-pill);
  padding: 10px 14px 10px 16px;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 14px;
  box-shadow: var(--shadow-sm);
  transition: transform var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out),
              background var(--duration-fast) var(--ease-out);
  cursor: default;
}
.rep-badge:hover {
  background: var(--color-cream);
  transform: translateY(-2px);
  box-shadow: var(--shadow-gold-hover);
}
.rep-badge__label,
.rep-flag__label {
  letter-spacing: 0.01em;
  /* S245 row 133: the label's line box is the same 22px as its count badge. At the theme's own 1.6 line height (22.4px at 14px, 20.8px at 13px,
     19.2px at 12px) the label sat a fraction of a pixel off the badge's top, so the label text, the ring and the digit were snapped to whole
     pixels differently from one page position to the next: at 1280 the ring sat on the middle of the capital letters at 16 of 20 positions and
     a whole pixel low at the other 4 (a whole pixel or more low at 12 of 20 at 360). With both 22px they share one top and one rounding, and
     nothing depends on where the page puts the pill: the ring is 0.00px from the middle of the capitals at 14px, 0.31px below it at 12px (0.31px
     above it at 13px, with the lift in the 600 block below), and the digit is 0.06px to 0.13px low of its ring, at every position and every width. */
  line-height: 22px;
}
.rep-badge__count {
  background: var(--color-cream);
  color: var(--color-navy);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-pill);
  min-width: 22px;
  height: 22px;
  /* S245 row 133 (Rob, the 9th of October 2026, on S244-122: "the number looks a pixel too high"). MEASURED on the live page by the painted ink at
     8 times scale: the digit sat about 0.9px HIGH of its ring's centre at half of all page positions and 0.06px to 0.13px low at the other half. The ring and
     the digit's line box are each snapped to whole pixels, and they snap the same way at every position only when the line box starts a whole
     number of pixels below the ring's top; with no padding it started 5.5px below (22px badge, one 11px line). 1px of top padding and none
     below makes it 6px, so the digit paints 0.06px to 0.13px low of the ring's centre at every position, at 1280 and at 360, at device scale 1,
     2 and 4. The same pair of numbers as .mi-menu-count (padding 1px top and 0 bottom, S220, 14/09/2026: fixed at Rob's request on his phone and not raised again). The badge stays 22px by 22px. */
  padding: 1px 6px 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-heading);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  flex-shrink: 0;
}

/* ── Negative flags ──────────────────────────────────────────────────────── */
.rep-flags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-md);
  justify-content: center;
}
/* S244 row 122 (Rob 08/10 ~18:5x: "Just make that a normal panel. But make the counter badge with the red colours."): a flag pill is
   the positive .rep-badge pill above value for value (white ground, 1.5px gold border, navy Montserrat 700 at 14px, the card shadow,
   padding 10px 14px 10px 16px); the orange border and orange text it had are gone. Its count badge is the .rep-badge__count box above
   (22px high, 22px wide at least, 1.5px border, 11px Montserrat 700) in the site's red: --color-error #C41C1C for the digit and the
   border, --color-error-bg for the ground, the same trio as .tier-status--err and the negative review qualifier (39.4). */
.rep-flag {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-sm);
  background: var(--color-surface);
  color: var(--color-navy);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-pill);
  padding: 10px 14px 10px 16px;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 14px;
  box-shadow: var(--shadow-sm);
  cursor: default;
}
.rep-flag__count {
  background: var(--color-error-bg);
  color: var(--color-error);
  border: 1.5px solid var(--color-error);
  border-radius: var(--radius-pill);
  min-width: 22px;
  height: 22px;
  /* S245 row 133: padding 1px top and 0 bottom, exactly as .rep-badge__count above (this is Rob's S244-122 badge: its digit sat 0.94px high). */
  padding: 1px 6px 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-heading);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  flex-shrink: 0;
}

/* ── Combined info panel ─────────────────────────────────────────────────── */
.rep-info-panel {
  display: flex;
  flex-direction: row;
  gap: 0;
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  margin-top: var(--sp-xl);
  overflow: hidden;
}
.rep-info-panel__col {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-sm);
  padding: var(--sp-xl) var(--sp-2xl);
  text-align: center;
}
.rep-info-panel__icon {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--color-cream);
  border: 1.5px solid var(--color-gold);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  box-shadow: var(--shadow-sm);
}
.rep-info-panel__text {
  font-size: 14px;
  color: var(--color-text-secondary);
  line-height: 1.6;
  text-wrap: pretty;
}
.rep-info-panel__divider {
  width: 1px;
  background: var(--color-gold);
  opacity: 0.4;
  flex-shrink: 0;
  margin: var(--sp-xl) 0;
}

/* ── Responsive ──────────────────────────────────────────────────────────── */
@container vp (max-width: 1024px) {
  .rep-info-panel { flex-direction: column; }
  .rep-info-panel__divider { width: auto; height: 1px; margin: 0 var(--sp-xl); }
}
@container vp (max-width: 768px) {
  .rep-hero { padding: var(--sp-2xl) var(--sp-xl); }
  .rep-hero__num-big { font-size: 52px; }
  .rep-section { padding: var(--sp-xl) var(--sp-lg); }
  .rep-empty { padding: var(--sp-xl) var(--sp-lg); }
  .rep-building { padding: var(--sp-xl) var(--sp-lg) var(--sp-2xl); }
}
@container vp (max-width: 600px) {
  .rep-hero__num-big { font-size: 44px; }
  .rep-hero__num-denom { font-size: 22px; }
  .rep-stars svg { width: 32px !important; height: 32px !important; }
  .rep-badge,
  .rep-flag { font-size: 13px; padding: 9px 15px 9px 13px; }
  /* S245 row 133: at 13px the capitals are shorter than at 14px, so the ring sat 0.69px below their middle; one whole pixel of lift puts it 0.31px above
     (the best whole pixels can do, as .mi-menu-count's -1.391px lift does on the gold tabs), the digit 0.13px low of the ring. 12px (next block) needs none. */
  .rep-badge__count,
  .rep-flag__count { position: relative; top: -1px; }
}
@container vp (max-width: 480px) {
  .rep-hero__num-big { font-size: 36px; }
  .rep-hero__num-denom { font-size: 18px; }
  .rep-stars svg { width: 28px !important; height: 28px !important; }
  .rep-stars { gap: 5px; }
  .rep-badge,
  .rep-flag { font-size: 12px; padding: 8px 12px; }
  .rep-badge__count,
  .rep-flag__count { top: 0; }
  .rep-privacy { flex-direction: column; gap: var(--sp-sm); text-align: center; align-items: center; }
}
/* end of §58 Reputation */
.dash-section__cta .btn.btn--primary,
.dash-section__cta .btn.btn--primary:hover,
.dash-section__cta .btn.btn--primary:focus {
  border: 2px solid var(--color-gold) !important;
  background: var(--color-cream) !important;
  color: var(--color-navy) !important;
}
.dash-section__cta .btn.btn--primary:hover {
  background: var(--color-cream-hover) !important;
  transform: translateY(-1px);
  box-shadow: var(--shadow-gold-hover) !important;
}
/* R3-11 24/09/26 (D-640): removed. This reset .cal__nav-btn to a plain grey-bordered transparent
   circle at rest (border var(--color-border-strong), background transparent), which is the
   "unstyled chevron" Rob reported - it was overriding the one correct rule at 46.X with
   !important. Rule of one: the correct definition lives in exactly one place now, at 46.X. */

/* 46.Y2 Calendar cell hover — all cells go green on hover (Rob 06/06/26).
   Today (cream/gold) and selected (green) modifiers preserved with !important
   so they survive Seeko's button:hover overrides. */
.cal__cell:hover {
  background: var(--color-success-bg) !important;
  border: 1.5px solid var(--color-success) !important;
  color: var(--color-success) !important;
}
/* S221 (14/09/26): `position: relative !important; left: -1px !important;` deleted here and on
   the selected block below. It moved today and the selected day one pixel left of every other
   circle and of the weekday label above them, and a state is colour only. */
.cal__cell--today,
.cal__cell--today:focus {
  background: var(--color-cream) !important;
  border: 1.5px solid var(--color-gold) !important;
  color: var(--color-navy) !important;
  /* D-651 (S235 FIXER-SHADOWS-3, 24/09/26): !important to match this rule's own siblings and to
     beat the parent theme's non-important button:focus{box-shadow:...} (documented at 46.CAL1
     above) the same way border/background already do here. */
  box-shadow: var(--shadow-gold-hover) !important;
}
.cal__cell--today:active {
  box-shadow: none !important;
}
.cal__cell--today:hover {
  background: var(--color-success-bg) !important;
  border: 1.5px solid var(--color-success) !important;
  color: var(--color-success) !important;
}
.cal__cell--sel,
.cal__cell--sel:hover,
.cal__cell--sel:focus,
.cal__cell--today.cal__cell--sel,
.cal__cell--today.cal__cell--sel:hover,
.cal__cell--today.cal__cell--sel:focus {
  background: var(--color-success-bg) !important;
  border: 1.5px solid var(--color-success) !important;
  color: var(--color-success) !important;
  font-weight: 700 !important;
}
/* S190: the going ring joins the !important block, or it could never show on a day that is also
   today or selected - both of those set `border` with !important above. It is placed LAST so a
   day the member holds a place on keeps its green circle whatever else that day is; today's cream
   fill and the selected state's tint and bold text are untouched, so nothing loses its signal. */
.cal__cell--going,
.cal__cell--going:hover,
.cal__cell--going:focus,
.cal__cell--today.cal__cell--going,
.cal__cell--today.cal__cell--going:hover,
.cal__cell--today.cal__cell--going:focus {
  border: 1.5px solid var(--color-success) !important;
}

/* 46.Z Disabled state — visually IDENTICAL to the active state. The JS
   disables the button during AJAX as a guard against double-clicks; the
   Randomise button also swaps its text to "Loading…". No dim, no opacity,
   no wait cursor — the text change alone is the feedback. */
/* S222: 46.Z above says in its own words "No dim, no opacity", and then this rule dimmed it to
   .45 anyway, so the calendar's own Loading... state contradicted the very comment that governs
   it. COMPUTED before: rgb(142,152,199) on rgb(255,253,244), 2.76 to 1. Now it matches the two
   rules underneath it, which were already at opacity 1. */
/* Row 8, "when you click one, both of them display the click animation" (Rob 06/10/26). The JS in
   profile-system.php disables BOTH Prev and Next while the week loads (the double-click guard), and this
   rule painted every disabled week button as pressed, so both went dark and lost their shadow. The look
   stays, but only the dashboard button the pointer is on (the one just clicked, which a tap also leaves
   hovered) takes it; the other disabled one keeps its rest look from the base rule above. Every other
   week-nav button (the event page's series pager, disabled at either end) is selected as before. */
.week-nav__btn:disabled:not(.dashboard-week-nav-btn),
.week-nav__btn[disabled]:not(.dashboard-week-nav-btn),
.dashboard-week-nav-btn:disabled:hover,
.dashboard-week-nav-btn[disabled]:hover {
  border: 2px solid var(--color-gold) !important;
  background: var(--color-cream-hover) !important; /* R3-03 24/09/26, D-640: in-flight is darker cream, not rest cream. */
  color: var(--color-navy) !important;
  opacity: 1 !important;
  cursor: not-allowed !important;
  box-shadow: none !important;
}
/* Row 8: a disabled dashboard week button with the pointer elsewhere keeps the rest look the base rule gives it. The one thing
   it must still be kept from is the parent theme's opacity: .65 for any disabled button (theme-static.min.css, button:disabled),
   which the site-wide rule above used to cancel and no longer reaches it. */
.dashboard-week-nav-btn:disabled:not(:hover),
.dashboard-week-nav-btn[disabled]:not(:hover) {
  opacity: 1 !important;
}
.dash-section__cta .btn.btn--primary:disabled,
.dash-section__cta .btn.btn--primary[disabled] {
  border: 2px solid var(--color-gold) !important;
  background: var(--color-cream) !important;
  color: var(--color-navy) !important;
  opacity: 1 !important;
  cursor: default !important;
  transform: none !important;
}
.cal__nav-btn:disabled,
.cal__nav-btn[disabled] {
  border: 1.5px solid var(--color-gold) !important; /* R3-11 24/09/26, D-640: was the grey/transparent mistake. */
  background: var(--color-cream-hover) !important;
  color: var(--color-navy) !important;
  opacity: 1 !important;
  cursor: default !important;
  box-shadow: none !important;
}

/* end of 46 */

/* ============================================================================
   47. SECTION: Gallery page — design-agent port (Gallery.html, 2026-06-08)
   Ported VERBATIM from gallery.css in design handover bundle.
   Container-query root (#item-body, container-name: vp) already established
   at §42.0, so the design's @container vp rules fire as-is.
   ============================================================================ */

/* 47.0 Design-agent token values, scoped to the gallery workspace so the page
   renders with the design agent's EXACT values. */
.workspace[data-screen-label="Gallery"] {
  --color-navy: #031B83;
  --color-navy-light: #0A2DAA;
  --color-gold: #CC9900;
  --color-gold-dark: #80641D;
  --color-gold-light: #FFD700;
  --color-cream: #FFFBE6;
  --color-cream-hover: #FFF5CC;
  --color-bg: #F8F8F8;
  --color-surface: #FFFFFF;
  --color-surface-raised: #F8F7F4;
  --color-surface-sunken: #F3F2EF;
  --color-text: #1A1A2E;
  --color-text-secondary: rgba(3, 27, 131, 0.75);
  --color-text-muted: rgba(3, 27, 131, 0.65);  /* S229 (T-S215-009 d), Rob: navy at 55 per cent reads grey; 65 reads blue. */
  --color-border: rgba(26, 26, 46, 0.08);
  --color-border-strong: rgba(26, 26, 46, 0.15);
  --color-success: #27A644;
  --color-success-bg: rgba(39, 166, 68, 0.08);
  --color-error: #C41C1C;
  --color-error-bg: rgba(196, 28, 28, 0.06);
  --color-info: #2563EB;
  --color-warning: #D97706;
  --color-warning-bg: rgba(217, 119, 6, 0.08);
  --sp-xs: 4px;
  --sp-sm: 8px;
  --sp-md: 12px;
  --sp-lg: 16px;
  --sp-xl: 24px;
  --sp-2xl: 32px;
  --sp-3xl: 48px;
  --sp-4xl: 64px;
  --radius-sm: 4px;
  --radius-md: 16px;
  --radius-lg: 16px;
  --radius-pill: 9999px;
  --shadow-sm: 0 1px 2px rgba(26, 26, 46, 0.04), 0 2px 4px rgba(26, 26, 46, 0.04);
  --shadow-md: 0 2px 4px rgba(26, 26, 46, 0.04), 0 4px 12px rgba(26, 26, 46, 0.08);
  --shadow-lg: 0 8px 24px rgba(26, 26, 46, 0.10), 0 16px 48px rgba(26, 26, 46, 0.06);
  --shadow-gold-hover: 0 4px 12px rgba(0, 0, 0, 0.16);
  --font-heading: 'Montserrat', system-ui, sans-serif;
  --font-body: 'Nunito Sans', system-ui, sans-serif;
  --duration-fast: 150ms;
  --duration-normal: 250ms;
  --duration-slow: 400ms;
  --ease-out: cubic-bezier(0.25, 1, 0.5, 1);
}

/* =========================================================================
   47.1 Toolbar
   ========================================================================= */
.gal-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-md);
  margin-bottom: var(--sp-xl);
  flex-wrap: wrap;
}
.gal-toolbar__left  { display: flex; align-items: center; gap: var(--sp-sm); flex-wrap: wrap; }
.gal-toolbar__right { display: flex; align-items: center; gap: var(--sp-sm); }

/* Upload button — primary gold */
.btn--upload {
    /* S207 05/09/26, Rob item A4: gold FILL out, light cream in with a gold border and navy text; darker cream on hover and select. */
  background: var(--color-cream, #FFFBE6);
  border: 2px solid var(--color-gold);
  color: var(--color-navy);
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 13px;
  padding: 9px 18px;
  border-radius: 10px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  transition: all var(--duration-fast) var(--ease-out);
  box-shadow: 0 2px 0 rgba(3,27,131,.10), 0 3px 6px rgba(3,27,131,.10);
}
.btn--upload:hover {
  background: var(--color-cream-hover, #FFF5CC);
  box-shadow: var(--shadow-gold-hover);
  transform: translateY(-1px);
}

/* Icon-toggle group (grid / masonry) */
.view-toggle {
  display: flex;
  border: 1.5px solid var(--color-gold);
  border-radius: 10px;
  background: var(--color-surface);
  flex-shrink: 0;
}
.view-toggle__btn {
  background: var(--color-surface);
  border: none;
  color: var(--color-navy);
  width: 36px;
  height: 36px;
  padding: 0;
  margin: 0;
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out);
}
.view-toggle__btn:first-child {
  border-radius: 10px 0 0 10px;
}
.view-toggle__btn:last-child {
  border-radius: 0 10px 10px 0;
}
.view-toggle__btn + .view-toggle__btn {
  border-left: 1.5px solid var(--color-gold);
}
.view-toggle__btn--active { background: var(--color-cream); }
.view-toggle__btn:hover:not(.view-toggle__btn--active) { background: var(--color-surface); }

/* Sort select */
.gal-sort {
  font: 600 13px var(--font-heading);
  color: var(--color-navy);
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: 10px;
  padding: 8px 12px;
  margin: 0;
  cursor: pointer;
  outline: none;
  height: 36px;
}

/* =========================================================================
   47.2 Stats strip
   ========================================================================= */
.gal-stats {
  display: grid;
  /* S203 03/09/26, Rob: "Those three panels should be centered under the title". The fourth 2fr track
     was a slot for a stat card that no longer exists, so the three cards sat left of centre (measured at
     1280: cards 361-842, title column midpoint 758.5). Three tracks at the width the 1fr share already gave
     them (150px measured), centred. The 768px rule below keeps its own three-column shape. */
  grid-template-columns: repeat(3, 150px);
  justify-content: center;
  gap: var(--sp-lg);
  margin-bottom: var(--sp-2xl);
}
.gal-stat {
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: var(--sp-lg) var(--sp-xl);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  box-shadow: 0 2px 6px rgba(3,27,131,.08), 0 3px 10px rgba(3,27,131,.06);
  text-align: center;
}
.gal-stat__val {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 32px;
  color: var(--color-gold);
  line-height: 1;
}
.gal-stat__lbl {
  font-size: 11px;
  color: var(--color-navy);
  font-family: var(--font-heading);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .09em;
}

/* =========================================================================
   47.3 Storage bar
   ========================================================================= */
.gal-storage {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--sp-xs);
  width: 100%;
}
.gal-storage__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-family: var(--font-heading);
  font-size: 12px;
  font-weight: 600;
  color: var(--color-text-muted);
  letter-spacing: .05em;
  text-transform: uppercase;
}
.gal-storage__bar {
  height: 10px;
  border-radius: 5px;
  background: var(--color-border);
  border: 1.5px solid var(--color-navy);
  overflow: hidden;
  padding: 1px;
}
.gal-storage__fill {
  height: 100%;
  border-radius: 3px;
  background: var(--color-gold-light);
  transition: width .4s var(--ease-out);
}

/* =========================================================================
   47.4 Albums grid - DELETED S229 16/09/26 on Rob's standing ruling (T-S204-005, D-243:
   "delete never hide"). The albums feature was removed by D-301; nothing on the platform
   emitted .albums-grid or .album-card any more (checked across mu-plugins and assets/js
   before deleting), so these 14 rules were dead weight. They are in git if ever needed.
   ========================================================================= */

/* =========================================================================
   47.5 Photos grid (uniform)
   ========================================================================= */
.photos-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: var(--sp-md);
}
.photo-card {
  position: relative;
  aspect-ratio: 1;
  border-radius: var(--radius-md);
  overflow: hidden;
  border: 1.5px solid var(--color-gold);
  cursor: pointer;
  transition: border-color var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out);
  box-shadow: 0 2px 6px rgba(3,27,131,.08), 0 3px 10px rgba(204,153,0,.14);
  background: var(--color-surface-sunken);
  display: grid;
  place-items: center;
}
.photo-card:hover {
  border-color: var(--color-gold);
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(3,27,131,.10), 0 8px 24px rgba(204,153,0,.26);
}
.photo-card--selected {
  /* S245 row 70 (Rob, the 7th of October 2026: "selected tiles have blue borders"; the visual lane's GALLERY-SEL-1 says gold): the selected tile's ring was navy (the card's own border and
     the 2px ring outside it). The card's border is already --color-gold; selected now keeps it and the 2px ring outside it is gold too. */
  border-color: var(--color-gold);
  box-shadow: 0 0 0 2px var(--color-gold);
}

/* 47.5.1 D-355 (S165) - the owner's own not-yet-approved photo. Only the owner is
   ever served one of these; other viewers' queries exclude pending photos server-side. */
.photo-card--pending {
  border-style: dashed;
}
.photo-card__pending-pill {
  position: absolute;
  top: 8px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  background: var(--color-gold);
  color: var(--color-navy); /* D055 */
  font-family: var(--font-heading, 'Montserrat', sans-serif);
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
  padding: 5px 9px;
  border-radius: 9999px;
  pointer-events: none;
  white-space: nowrap;
  max-width: calc(100% - 16px);
  overflow: hidden;
  text-overflow: ellipsis;
}
/* end of 47.5.1 */

/* Photo image fill */
.photo-card__thumb {
  width: 100%;
  height: 100%;
  display: grid;
  place-items: center;
  font-size: 32px;
  font-family: "Apple Color Emoji","Segoe UI Emoji",sans-serif;
  font-variant-emoji: emoji;
  background: var(--color-surface-sunken);
  background-image:
    repeating-linear-gradient(
      -45deg,
      transparent,
      transparent 6px,
      rgba(3,27,131,.04) 6px,
      rgba(3,27,131,.04) 12px
    );
}
.photo-card__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Hover overlay */
.photo-card__overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgba(0,0,0,.4) 0%, transparent 40%, transparent 60%, rgba(0,0,0,.4) 100%);
  opacity: 0;
  transition: opacity var(--duration-fast) var(--ease-out);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  padding: var(--sp-md);
}
.photo-card:hover .photo-card__overlay { opacity: 1; }

.photo-card__actions {
  display: flex;
  gap: 6px;
  justify-content: center;
  align-items: center;
  background: #fff;
  backdrop-filter: blur(6px);
  border-radius: 10px;
  padding: 5px 7px;
  border: 1.5px solid var(--color-gold);
  box-shadow: 0 2px 8px rgba(3,27,131,.15), 0 3px 12px rgba(204,153,0,.25);
}
.photo-card__action-btn {
  width: 28px !important;
  height: 28px !important;
  border-radius: 7px;
  background: var(--color-cream);
  border: 1.5px solid var(--color-gold);
  color: var(--color-navy);
  display: grid;
  place-items: center;
  padding: 0 !important;
  margin: 0 !important;
  line-height: 1 !important;
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out);
}
/* S213 item 36 (A4: gold buttons become light cream, DARKER cream on hover and select).
   This hover was still filling with solid gold. Border declared explicitly because Seeko's
   own button:hover sets border-color transparent and outranks a resting rule that leaves it
   undeclared, which is the fault Rob reported on the conversation icons (item 44). */
.photo-card__action-btn:hover { background: var(--color-cream-hover); color: var(--color-navy); border-color: var(--color-gold); }
.gal-fav-btn--active { color: #C41C1C; }
.gal-fav-btn--active svg { fill: #C41C1C; stroke: #C41C1C; }

.photo-card__caption {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 11px;
  color: #fff;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  letter-spacing: .05em;
  text-transform: uppercase;
  text-shadow: 0 1px 4px rgba(0,0,0,.6);
  max-width: 100%;
}

/* Checkbox top-left */
.photo-card__check {
  position: absolute;
  z-index: 3; /* S208 (worklist 2.13 lane-4 note): the tick sits above the later-sibling .photo-card__overlay so a real click reaches it; moved here from two inline styles */
  top: 8px;
  left: 8px;
  width: 20px;
  height: 20px;
  border-radius: 6px;
  border: 2px solid rgba(255,255,255,.6);
  background: rgba(255,255,255,.15);
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: all var(--duration-fast) var(--ease-out);
  backdrop-filter: blur(4px);
  opacity: 0;
}
.photo-card:hover .photo-card__check { opacity: 1; }
.photo-card--selected .photo-card__check {
  opacity: 1;
  background: #EAF4EC;
  border-color: #2F7D4F;
}
.photo-card--selected .photo-card__check::after {
  content: "";
  width: 12px;
  height: 12px;
  background: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 12.5l5 5L19 6.5' fill='none' stroke='%232F6B47' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center / contain;
}

/* Masonry variant */
.photos-grid--masonry {
  columns: 4;
  column-gap: var(--sp-md);
  display: block;
}
.photos-grid--masonry .photo-card {
  aspect-ratio: unset;
  break-inside: avoid;
  margin-bottom: var(--sp-md);
  display: block;
}
.photos-grid--masonry .photo-card__thumb {
  height: auto;
  min-height: 100px;
}

/* =========================================================================
   47.6 Selection bar
   ========================================================================= */
.selection-bar {
  position: sticky;
  top: 0;
  z-index: 20;
  background: #FFFFFF;
  color: var(--color-navy);
  border: 2px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: var(--sp-md) var(--sp-xl);
  margin-bottom: var(--sp-xl);
  /* S245 recaptures-s229 (registry rows T-S229-050 and T-S229-024: the Share and Delete buttons are clearly not centred in the bar). S245 row 70 took out the 9px
     vertical step (Seeko's button margin, margin 0 below). What is left is the other axis, MEASURED live from the painted pixels at 1280
     (grace_tamblyn, gallery, one photo selected): the Delete button sits 8.00px RIGHT of the bar's middle (space-between puts it midway between a
     65px count and the 48px X), and on a phone it sits 93px LEFT of it, hard against the left padding of its own row. Three columns,
     1fr | auto | 1fr, as the Messages compose row does (page-polish.css .msg-compose-actions), put the action dead centre whatever the count's
     width, with the count first and the X last; the phone block below puts the button on the middle of its own row. */
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  column-gap: var(--sp-lg);
  box-shadow: var(--shadow-md);
  animation: bar-slide-in .2s var(--ease-out);
}
@keyframes bar-slide-in { from { opacity:0; transform: translateY(-8px); } to { opacity:1; transform:none; } }
.selection-bar__count {
  grid-column: 1;
  justify-self: start;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 14px;
  color: var(--color-navy);
}
/* Equal columns, so Share and Delete both take the wider label's width (D-530). */
.selection-bar__actions {
  grid-column: 2;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: var(--sp-sm);
}
/* S245 row 70 (Rob, the 7th of October 2026, on the gallery selection bar: "in the bar the labels are not on one row, Share's hover loses its border and its text goes black, Delete's hover as
   before ... the 'close panel X' ... copied from the viewer's, which is perfect; this one is too small and left-aligned"; D-786). The bar's contents are the code lane's (T-S243-022); this is its
   look. MEASURED LIVE on example_oliver_hartnell's gallery with one photo selected, at 1280: "1 selected" centred at 891.75, Delete and the X at 882.77, a 9px step. CAUSE: Seeko's own button rule
   (seeko-dynamic.css `button { margin-bottom: 1rem }`, 18px here) reaches both buttons, because neither class restated margin; a flex row centres the MARGIN box, so each button sat 9px above the row's
   centre while the count (a span) sat on it. `margin: 0` on both. The hover rules set `background` only, so Seeko's `button:hover` (color #191919, border-color transparent) kept the other two
   properties: that is Share and Delete "losing the border and going black" (da.md 17a: specificity wins per property, so every property the theme's rule sets is restated). Both buttons take the
   ONE shadow at rest (--shadow-gold-hover, S245 row 130), the one-pixel lift on a real pointer, and a held state that is the darker wash with its ring and no shadow, the same as every button
   in 43. The X is the viewer's own (.gal-lightbox__close, 47.7 below): 48px, cream, 2px gold ring, the shadow, the same hover and held states; the glyph is the same 24px svg already inside it. */
.selection-bar > .selection-bar__btn { grid-column: 2; }
.selection-bar__btn {
  background: var(--color-cream);
  border: 2px solid var(--color-gold);
  color: var(--color-navy);
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 13px;
  line-height: 1;
  padding: 8px 16px;
  margin: 0;
  border-radius: 10px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-sm);
  box-shadow: var(--shadow-gold-hover);
  transition: background var(--duration-fast) var(--ease-out), box-shadow 120ms ease-out, transform 120ms ease-out;
}
.selection-bar__btn:hover {
  background: var(--color-cream-hover);
  border-color: var(--color-gold);
  color: var(--color-navy);
  box-shadow: var(--shadow-gold-hover);
  transform: translateY(-1px);
}
.selection-bar__btn:not([disabled]):not(.disabled):active {
  background: var(--color-cream-hover);
  border-color: var(--color-gold);
  color: var(--color-navy);
  box-shadow: none;
  transform: none;
}
.selection-bar__btn--danger {
  background: var(--color-error-bg);
  border-color: var(--color-error);
  color: var(--color-error);
}
.selection-bar__btn--danger:hover {
  background: rgba(196,28,28,.12);
  border-color: var(--color-error);
  color: var(--color-error);
}
.selection-bar__btn--danger:not([disabled]):not(.disabled):active {
  background: rgba(196,28,28,.12);
  border-color: var(--color-error);
  color: var(--color-error);
}
/* S229 16/09/26 (T-S229-050), Rob: "the X should be in a circle as per my previous
   description" - the small circle, cream fill, gold border, blue X. */
.selection-bar__close {
  grid-column: 3;
  justify-self: end;
  background: var(--color-cream);
  border: 2px solid var(--color-gold);
  color: var(--color-navy);
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
  padding: 0;
  margin: 0;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  box-shadow: var(--shadow-gold-hover);
  transition: background var(--duration-fast) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out);
}
.selection-bar__close:hover {
  background: var(--color-cream-hover);
  border-color: var(--color-gold);
  color: var(--color-navy);
  box-shadow: var(--shadow-gold-hover);
  transform: translateY(-1px);
}
.selection-bar__close:not([disabled]):not(.disabled):active {
  background: var(--color-cream-hover);
  border-color: var(--color-gold);
  color: var(--color-navy);
  box-shadow: none;
  transform: none;
}

/* =========================================================================
   47.7 Lightbox
   ========================================================================= */
.gal-lightbox {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(3,10,40,.92);
  display: flex;
  align-items: center;
  justify-content: center;
  animation: gal-lb-fade .2s var(--ease-out);
  padding: var(--sp-xl);
}
@keyframes gal-lb-fade { from { opacity:0; } to { opacity:1; } }
.gal-lightbox__inner {
  position: relative;
  max-width: 900px;
  width: 100%;
  background: var(--color-surface);
  border: 2px solid var(--color-gold);
  border-radius: var(--radius-md);
  overflow: hidden;
  box-shadow: 0 32px 80px rgba(0,0,0,.6);
  /* S227 item 60: named rows so prev/next get their own centred row BELOW the
     picture instead of lying on top of it. The 1fr columns either side centre
     the pair; column-gap is the space between the two buttons. */
  /* S229 16/09/26 (T-S229-051), Rob: the arrows and the buttons share ONE row, centred as a
     group, with Tag and Share on the left and Download and Delete on the right. The nav
     buttons moved into the footer in the markup, so the grid is back to two plain rows. */
  display: grid;
  grid-template-columns: 1fr;
  grid-template-areas:
    "img"
    "meta";
}
.gal-lightbox__img  { grid-area: img; }
.gal-lightbox__meta { grid-area: meta; }
.gal-lightbox__img {
  width: 100%;
  /* Height comes from the picture. The !important is here for one reason: the
     gallery markup writes height:<n>vh onto this element as an inline style
     (profile-system.php 7149). When the code lane drops that inline write, this
     declaration can lose the flag. */
  height: auto !important;
  max-height: none;
  background: #FFFFFF;
  background-image: none;
  border-bottom: 2px solid var(--color-gold);
  display: grid;
  place-items: center;
  font-size: 48px;
  font-family: "Apple Color Emoji","Segoe UI Emoji",sans-serif;
  font-variant-emoji: emoji;
}
.gal-lightbox__img img {
  /* width:auto with max-width:100% keeps the aspect ratio while the 60vh cap
     applies, so a portrait photo narrows instead of squashing and the wrapper
     still ends exactly where the picture ends. object-fit is not needed once
     the box IS the picture. */
  width: auto;
  max-width: 100%;
  height: auto;
  max-height: 60vh;
  margin-inline: auto;
  display: block;
}
.gal-lightbox__meta {
  padding: var(--sp-lg) var(--sp-xl);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-lg);
  flex-wrap: wrap;
}
.gal-lightbox__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 18px;
  color: var(--color-navy);
}
.gal-lightbox__sub {
  font-size: 13px;
  color: var(--color-text-muted);
  margin-top: 2px;
}
.gal-lightbox__btns { display: flex; gap: var(--sp-sm); align-items: center; }
/* S229: the footer is one centred row. The photo's name keeps the far left; the two button
   groups and the arrows sit together in the middle of the row. */
.gal-lightbox__meta {
  display: flex !important;
  align-items: center;
  justify-content: center;
  gap: 12px;
  flex-wrap: wrap;
}
/* S229: the name sits at the far left without pushing the centred group off centre. */
.gal-lightbox__meta { position: relative; padding-left: 96px; padding-right: 96px; }
.gal-lightbox__meta > div:first-child { position: absolute; left: var(--sp-md); top: 50%; transform: translateY(-50%); max-width: 84px; }
.gal-lightbox__meta .gal-lightbox__nav {
  width: 40px; height: 40px; font-size: 32px; margin: 0;
}
.gal-lightbox__btns .btn { line-height: 1; align-items: center; }
/* S245 recaptures-s229 (registry row T-S229-051: the icon-to-label centring is off, measure the ink). MEASURED at dpr 8 and dpr 1 on the live
   lightbox footer (grace_tamblyn, gallery, 1280): the Download and Delete icons paint on their button's centre (-0.002 and -0.004 at dpr 8),
   but the Tag person icon paints 1.155px BELOW it (1.143 at dpr 1) because its drawing sits low in its own 24-unit box (head and shoulders
   run 7 to 21 of 24, so its ink centre is 2 units, 1.17px at 14px, under the box centre). The phone block below already lifts it by 1px
   (FF02-20); the same 1px, copied from there, is now the base value so the desktop footer matches. One pixel, because dpr 1 cannot move
   text or icons by a fraction. */
.gal-lb-tag svg { transform: translateY(-1px); }
/* R3-18 (Rob 26/09: "check the label on the delete button. It looks a little low"): measured by painted ink at 412/2.625
   (results/s235/ink-raster/delete-412.png, tools/ink_raster.js) the word sits 0.25px below the button's midline, inside
   the 0.5px tolerance. Every padding, height and line-height split tried (nine deploys) snapped the glyph row a whole
   pixel up to 0.75px HIGH instead, because the row lands on whole pixels inside the flex box (LB-460); 0.25px low is
   the nearest position that exists, so the shared .btn--sm values stand unchanged. */
/* R3-16 (24/09/2026): the Share button's "Copied!" state (profile-system.php ~8457) added
   no class of its own, so it kept the standard gold look. Rob: it should read as the
   platform's confirmation green with no shadow, then reset to standard. The ID beats
   .btn.btn--primary's own 2 classes without needing !important on every property. */
#gal-lb-share.gal-lb-share--copied {
    background: var(--color-success-bg) !important;
    border-color: var(--color-success) !important;
    color: var(--color-success) !important;
    box-shadow: none !important;
}
/* Close + prev/next now match the dashboard pagination pill style
   (.week-nav__btn §46.X): cream fill, gold border, navy glyph, cream-hover
   with gold shadow. Glyphs sized to fill the circle so they're readable
   instead of a tiny mark floating in a big empty pill (Rob 08/07/26). */
.gal-lightbox__close,
.gal-lightbox__nav {
  position: absolute;
  border-radius: 50%;
  background: var(--color-cream) !important;
  border: 2px solid var(--color-gold) !important;
  color: var(--color-navy) !important;
  font-family: var(--font-heading);
  font-weight: 700;
  line-height: 1;
  padding: 0 !important;
  display: flex !important;
  align-items: center;
  justify-content: center;
  text-align: center;
  cursor: pointer;
  box-shadow: var(--shadow-gold-hover);
  transition: background var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-out);
}
.gal-lightbox__close:hover,
.gal-lightbox__nav:hover {
  background: var(--color-cream-hover) !important;
  color: var(--color-navy) !important;
  border-color: var(--color-gold) !important;
  box-shadow: var(--shadow-gold-hover, 0 4px 10px rgba(0, 0, 0, 0.25));
  transform: translateY(-1px);
}
.gal-lightbox__close:active,
.gal-lightbox__nav:active { box-shadow: none; transform: none; }
.gal-lightbox__close {
  top: var(--sp-md); right: var(--sp-md);
  width: 48px; height: 48px;
  font-size: 36px;   /* +20% per Rob 08/07/26 */
}
.gal-lightbox__nav {
  position: static;
  top: auto; left: auto; right: auto;
  transform: none;
  margin: 16px 0 0;
  width: 56px; height: 56px;
  font-size: 48px;   /* +20% per Rob 08/07/26 */
}
.gal-lightbox__nav--prev { grid-area: prev; }
.gal-lightbox__nav--next { grid-area: next; }
.gal-lightbox__nav--prev:hover,
.gal-lightbox__nav--next:hover { transform: translateY(-1px); }
.gal-lightbox__nav--prev:active,
.gal-lightbox__nav--next:active { transform: none; }

/* FF02-20: keep the complete lightbox inside a phone viewport and stack its
   controls in three centred rows: arrows, Tag/Share, Download/Delete. */
@media (max-width: 600px) {
  .gal-lightbox {
    padding: 12px;
  }
  .gal-lightbox__inner {
    width: calc(100vw - 24px);
    max-width: 900px;
    margin: auto;
  }
  .gal-lightbox__img {
    min-width: 0;
    display: grid;
    place-items: center;
  }
  .gal-lightbox__img img {
    max-width: 100%;
    object-fit: contain;
    object-position: center;
    margin-inline: auto;
  }
  .gal-lightbox__meta {
    position: static;
    display: grid !important;
    grid-template-columns: auto auto;
    grid-template-areas:
      "prev next"
      "left left"
      "right right"
      "title title";
    justify-content: center;
    justify-items: center;
    align-items: center;
    gap: 12px 16px;
    padding: 14px 10px 18px;
  }
  .gal-lightbox__meta > div:first-child {
    grid-area: title;
    position: static;
    transform: none;
    max-width: none;
    text-align: center;
  }
  .gal-lightbox__btns--left {
    grid-area: left;
    justify-content: center;
  }
  .gal-lightbox__btns--right {
    grid-area: right;
    justify-content: center;
  }
  .gal-lightbox__nav {
    position: static;
    margin: 0;
    width: 56px;
    height: 56px;
    font-size: 48px;
  }
  .gal-lightbox__nav--prev {
    grid-area: prev;
    justify-self: end;
  }
  .gal-lightbox__nav--next {
    grid-area: next;
    justify-self: start;
  }
  .gal-lb-tag svg {
    width: 17px;
    height: 17px;
  }
}

/* =========================================================================
   47.8 Tab content + empty states
   ========================================================================= */
.gal-tab-content {
  min-height: 70vh;
}
.gal-empty {
  text-align: center;
  padding: var(--sp-4xl) var(--sp-xl);
  color: var(--color-text-secondary);
}
.gal-empty__icon { font-size: 48px; margin-bottom: var(--sp-lg); }
.gal-empty__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 20px;
  color: var(--color-navy);
  margin-bottom: var(--sp-sm);
}
.gal-empty__hint { font-size: 15px; text-wrap: pretty; margin-bottom: var(--sp-xl); }

/* =========================================================================
   47.9 Section heading row
   ========================================================================= */
.gal-heading-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--sp-lg);
  gap: var(--sp-md);
}
.gal-heading {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 16px;
  color: var(--color-navy);
  display: inline-flex;
  align-items: center;
  gap: var(--sp-sm);
}
.gal-heading__count {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 11px;
  background: var(--color-cream);
  color: var(--color-navy);
  border: 1.5px solid var(--color-gold);
  border-radius: 50%;
  width: 20px;
  height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  line-height: 1;
  /* S234 21/09/26, Rob on the count bubbles: "the number ... is low". MEASURED on the gallery's
     own "All Photos" and "Tagged" bubbles at device scale 8 against the painted gold ring: with no
     padding at all the digits paint 0.63px BELOW the ring's centre, because line-height 1 centres
     the EM square and a digit is cap height with no descender, so the spare room all sits above
     it. The ink lands on whole device rows here, so the lever is coarse: padding-bottom anywhere
     from 1px to 2.5px lifts it one row, to 0.38px, and 3px overshoots to 1.38px high. 1.5px is
     the middle of the plateau. Padding moves the ink by half its value and the bubble is
     border-box, so the circle itself is unchanged at 20px.
     S245 row 133: the 1.5px was the middle of that plateau at ONE page position. MEASURED across the whole cycle of positions at 1280 and 360:
     the digit sat 0.88px HIGH of the ring's centre at a quarter of them, because 1.5px starts the digit's line box 3.75px below the ring's top,
     which is not a whole pixel (see .rep-badge__count). 1px starts it 4px below: 0.13px low at every position, the same ink the 1.5px gave at its best. */
  padding-bottom: 1px;
}

/* =========================================================================
   47.10 Video card inline overlays
   ========================================================================= */
.photo-card__play-overlay {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%,-50%);
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--color-cream); border: 1.5px solid var(--color-gold);
  display: grid; place-items: center; color: var(--color-navy);
  font-size: 18px; pointer-events: none;
}
.photo-card__duration {
  position: absolute; bottom: 8px; right: 8px;
  background: var(--color-cream); color: var(--color-navy);
  font-family: var(--font-heading); font-weight: 700; font-size: 11px;
  padding: 2px 7px; border-radius: 6px; border: 1.5px solid var(--color-gold);
  pointer-events: none;
}

/* =========================================================================
   47.11 Responsive (container queries)
   ========================================================================= */
@container vp (max-width: 900px) {
  .photos-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
  .photos-grid--masonry { columns: 3; }
}
@container vp (max-width: 600px) {
  .photos-grid { grid-template-columns: repeat(3, 1fr); gap: var(--sp-sm); }
  .photos-grid--masonry { columns: 2; }
  .gal-toolbar { gap: var(--sp-sm); justify-content: center; }
  .gal-toolbar__left, .gal-toolbar__right { justify-content: center; }
  .gal-stat { padding: var(--sp-sm) var(--sp-md); }
}
@container vp (max-width: 480px) {
  .gal-stats {
    grid-template-columns: repeat(3, 1fr);
    gap: var(--sp-md);
  }
  .gal-stat:last-child {
    grid-column: 1 / -1;
    flex-direction: row;
    gap: var(--sp-lg);
    align-items: center;
  }
  .gal-storage { flex: 1; }
}
@container vp (max-width: 400px) {
  .photos-grid { grid-template-columns: repeat(2, 1fr); }
}

/* end of 47 */

/* ============================================================================
   48 SECTION: Universal Dropdown System (S111, 24/06/26 · amended same day)
   ============================================================================
   Canonical COLOURS and INTERACTION for every custom dropdown / popover-with-
   options on the site. Modelled on §43 Universal Button System: every canonical
   property carries !important to defeat Seeko / BuddyPress / theme rules.
   Reference spec = the members-directory "Order By" dropdown (§26.5).
   Memory: project_canonical_dropdown.md.

   IMPORTANT — sizes are NOT canonical. Each dropdown instance picks its own
   height, padding, font-size, border-width, border-radius, min-width, gap, and
   positioning to fit its context. Canonical owns colours + state behaviour
   only (Rob 24/06/26: "every need for a drop down is going to want different
   sizes — it's just the styling that needs to be fixed — colours and
   interaction").

   Class hierarchy:
   - .dropdown                   wrapper
   - .dropdown__trigger          the button-style closed state
   - .dropdown__trigger--open    added when menu is open (flips border to navy)
   - .dropdown__caret            ▾ glyph (rotates when open)
   - .dropdown__menu             popup container
   - .dropdown__menu--open       added when open (drives fade-in)
   - .dropdown__option           each option pill
   - .dropdown__option--selected selected state (bold + cream + gold)

   Multi-select variant: identical visuals; multiple options carry --selected
   at once. Submit/Send uses .btn-option.

   Apply these classes ALONGSIDE existing JS-binding classes (additive). The
   per-instance CSS handles dimensions; canonical handles look + state.
   ========================================================================= */

/* 48.1 Trigger — colours + open state + caret behaviour only.
   No height/padding/font-size/border-radius — each instance sets its own. */
.dropdown__trigger {
    background: #FFFFFF !important;
    border-style: solid !important;
    border-color: #CC9900 !important;
    color: #031B83 !important;
    cursor: pointer !important;
    transition: background 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease !important;
}
/* Open: bg stays white; border flips navy; shadow deepens. */
.dropdown__trigger--open {
    background: #FFFFFF !important;
    border-color: #031B83 !important;
    color: #031B83 !important;
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.18) !important;
}
.dropdown__caret {
    transition: transform 0.2s ease !important;
}
.dropdown__trigger--open .dropdown__caret {
    transform: rotate(180deg) !important;
}

/* 48.2 Menu — colours + fade-in only. Each instance sets its own
   position / top / left / padding / gap / min-width / border-width /
   border-radius / list-style / display direction. */
.dropdown__menu {
    background: #FFFFFF !important;
    border-style: solid !important;
    border-color: #CC9900 !important;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18) !important;
    opacity: 0 !important;
    visibility: hidden !important;
    transition: opacity 0.18s ease, visibility 0.18s ease !important;
    z-index: 98 !important;            /* S245 row 35: 98, was 1000 (header is 99; see 26.5.7) */
}
.dropdown__menu--open {
    opacity: 1 !important;
    visibility: visible !important;
}

/* 48.3 Option pill — colours + states only. Each instance sets its own
   display / padding / font-size / font-weight (base) / border-width /
   border-radius / text-align / line-height / white-space. */
.dropdown__option {
    background: #FFFFFF !important;
    border-style: solid !important;
    border-color: rgba(3, 27, 131, 0.2) !important;
    color: #031B83 !important;
    cursor: pointer !important;
    user-select: none !important;
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease !important;
    list-style: none !important;
}
.dropdown__option:hover {
    background: #fffbe6 !important;
    border-color: #CC9900 !important;
    color: #031B83 !important;
}
.dropdown__option--selected,
.dropdown__option.is-selected {
    background: #fffbe6 !important;
    border-color: #CC9900 !important;
    color: #031B83 !important;
    font-weight: 700 !important;
}
.dropdown__option--selected:hover,
.dropdown__option.is-selected:hover {
    background: #fffbe6 !important;
    border-color: #CC9900 !important;
    color: #031B83 !important;
}
/* end of 48 */

/* =========================================================================
   §59 Public-profile Preferences + Reputation tabs — re-use dashboard
   card design (§58 .rep-*, §53 .pf-*) on the public profile.
   ========================================================================= */

/* .card was scoped to .workspace .card in §42 to avoid Bootstrap collisions.
   Re-apply on the public profile wrapper so .pf-card sections render. */
.profile-public-wrapper .card {
    background: var(--color-surface);
    border: 1.5px solid var(--color-gold);
    border-radius: var(--radius-md);
    padding: var(--sp-xl);
    box-shadow: var(--shadow-sm);
}
.profile-public-wrapper .card + .card { margin-top: var(--sp-lg); }

/* Width constraint + centring for the Preferences / Reputation tab panels. */
.profile-public-wrapper > .section#pub-preferences,
.profile-public-wrapper > .section#pub-reputation {
    max-width: 760px;
    margin-left: auto;
    margin-right: auto;
}

/* Reputation tab wrapper. */
.rep-public > * + * { margin-top: var(--sp-xl); }
.rep-public .rep-subtitle-wrap { margin-bottom: 0; }
.rep-public__subtitle {
    margin: 0;
    text-align: center;
    color: var(--color-text-secondary);
    font-family: var(--font-body);
    font-size: 14px;
    line-height: 1.5;
}

/* Preferences tab — public variant of pf-hero (no top check row, no signal). */
.pf-public .pf-hero--public {
    background: var(--color-surface);
    border: 1.5px solid var(--color-gold);
    border-radius: var(--radius-md);
    padding: var(--sp-xl);
    box-shadow: var(--shadow-sm);
}
.pf-public .pf-hero--public .pf-result {
    display: flex;
    align-items: center;
    gap: var(--sp-lg);
    justify-content: center;
    text-align: left;
    padding-top: 21px;
}
.pf-public .pf-hero--public .pf-result__emoji {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 26px;
    flex: 0 0 auto;
    border: 1.5px solid var(--color-gold);
}
.pf-public .pf-hero--public .pf-result__body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 0 1 auto;
}

/* Narrow viewport — stack hero vertically so the icon sits above the text
   (icon-on-left at <=480px crowds the layout and looks off-brand). */
@media (max-width: 480px) {
    .pf-public .pf-hero--public .pf-result {
        flex-direction: column;
        text-align: center;
        gap: var(--sp-md);
    }
    .pf-public .pf-hero--public .pf-result__body {
        align-items: center;
    }
}

/* Read-only badges - selected, no hover lift, no pointer.
   S224 14/09/26, Rob item 126: "There's too much space at the edges of the badges", and he
   ruled by AskUserQuestion that the WHOLE badge becomes the word plus 15px each side, so they
   get narrower rather than wider. MEASURED BEFORE on cold_prem21's public Preferences panel at
   1280: edge to first letter 28.00px on the LEFT and 20.00px on the RIGHT, so it was asymmetric
   as well as wide. The cause of the extra 8 on the left is the .pf-badge__emoji span, which is
   EMPTY on the public panel and 0px wide but still earns the flex gap. Hiding an empty span
   removes it from the flex line, so the gap goes with it; 13px of padding plus the 2px border
   then reads exactly 15.00px on both sides. Culture Vulture 147.61 -> 129.61, Sporty 91.69 ->
   73.69, Tea Drinker 122.30 -> 104.30, each narrower by 18px, height unchanged at 47.19.
   SCOPED to the read-only panel on purpose: the picker's own badges DO carry an emoji, and Rob
   14/09/26: "If it's something that is global, I'll state for definite it's global ... don't
   assume that it is." */
.pf-badges--readonly .pf-badge {
    cursor: default;
    padding-left: 13px;
    padding-right: 13px;
    background: var(--color-cream, #FFFBE6);
    border-color: var(--color-gold, #CC9900);
    color: var(--color-navy, #031B83);
}
.pf-badges--readonly .pf-badge__emoji:empty {
    display: none;
}
.pf-badges--readonly .pf-badge:hover {
    transform: none;
}

/* Interest pills inside Top interests card. */
.pf-public__interests {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-sm);
    justify-content: center;
    margin-top: 20px;
}
.pf-public__pill {
    display: inline-flex;
    align-items: center;
    padding: 6px 14px;
    border: 1px solid var(--color-gold);
    border-radius: var(--radius-pill);
    background: var(--color-surface);
    color: var(--color-navy);
    font-family: var(--font-body);
    font-size: 13px;
    font-weight: 600;
}

/* Empty state — no preferences yet. */
.pf-public--empty {
    text-align: center;
    padding: var(--sp-3xl) var(--sp-xl);
}
.pf-public__empty-text {
    margin: 0;
    color: var(--color-text-secondary);
    font-family: var(--font-body);
    font-size: 14px;
}

/* end of 59 */

/* =========================================================================
   §60 Gallery polish — on-brand modal + toast, mobile selection bar,
   mobile-always-visible checkbox.
   ========================================================================= */

/* On-brand modal (replaces native prompt). */
.gal-modal-overlay {
    position: fixed; inset: 0; z-index: 300;
    background: rgba(3, 10, 40, .55);
    display: flex; align-items: center; justify-content: center;
    padding: var(--sp-xl);
    opacity: 0;
    transition: opacity .15s var(--ease-out);
}
.gal-modal-overlay.is-open { opacity: 1; }
.gal-modal {
    background: var(--color-surface);
    border: 1.5px solid var(--color-gold);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    padding: var(--sp-xl);
    width: 100%;
    max-width: 420px;
    transform: translateY(8px);
    transition: transform .2s var(--ease-out);
}
.gal-modal:has(.gal-modal__actions .btn--danger) {
    width: min(100%, 360px);
    padding: var(--sp-lg);
}
.gal-modal-overlay.is-open .gal-modal { transform: translateY(0); }
.gal-modal__title {
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 18px;
    color: var(--color-navy);
    margin: 0 0 var(--sp-sm);
    text-align: center;
}
.gal-modal__msg {
    font-size: 13px;
    color: var(--color-text-secondary);
    text-align: center;
    margin: 0 0 var(--sp-md);
}
/* S227 item 52: the theme gives every <p> margin-bottom:27px with margin-top:0,
   so the paragraph in the tag modal's scroll wrapper pushed Done 41.00px away
   while the heading above it sat 14.00px away (measured, 1280). The modal
   body's own 14px is the gap that is wanted; the theme's is not. */
.gal-modal p {
    margin: 0;
}
.gal-modal__input {
    width: 100%;
    box-sizing: border-box;
    padding: 10px 14px;
    border: 1.5px solid var(--color-gold);
    border-radius: var(--radius-pill);
    background: var(--color-cream);
    font-family: var(--font-body);
    font-size: 15px;
    color: var(--color-navy);
    margin-bottom: var(--sp-lg);
}
html[data-nav="kbd"] .gal-modal__input:focus {
    outline: none;
    box-shadow: 0 0 0 3px rgba(3, 27, 131, .15);
}
/* 60.1 S227 item 58, the "Delete this photo?" confirmation. Rob circled Cancel; it stands as
   triaged ("review the Cancel/OK button styling and order"). Measured live at all five of his
   widths: Cancel was bare text (background rgba(0,0,0,0), border 0px, 600 weight) beside a
   bordered OK, and the side-by-side pair was 74.64 against 55.50.
   The row now uses the platform's OWN equal-pair mechanism, the one already carrying his item
   225 at .uks-card__actions: an intrinsic grid whose 1fr columns both size to the WIDER button
   inside a fit-content box, so the longer label gets its 15px each side and the shorter button
   matches it, and the row still centres. A one-button row (the tag modal's Done) still hugs
   its own label and still centres, exactly as the flex version did.
   The dismiss face is Rob's own on image 68, about the same button in the same kind of modal:
   "make the 'not now' button the same width" and "Leave the background white but give it a
   gold border". .btn--subtle itself is untouched - it is the platform's shared inline text
   link, used by the questionnaire's Skip - so this is scope, not a second source of truth.
   No shadow: OK computes box-shadow none on this surface (the gal-modal is appended to <body>,
   outside .workspace, so the platform's two-part navy shadow never reaches it) and the pair
   must match. The hover sits inside @media (hover: hover) for his item 64 ruling, so a tap on a
   phone cannot leave the button painted. --color-cream-hover carries its fallback because that
   token is defined only inside .workspace[data-screen-label="Gallery"] and .uks-page-shell,
   neither of which contains this modal. THE ORDER IS UNCHANGED: that is Rob's call. */
.gal-modal__actions {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    width: fit-content;
    margin-left: auto;
    margin-right: auto;
    gap: var(--sp-sm);
}
.gal-modal__actions .btn {
    padding-left: 15px;
    padding-right: 15px;
}
.gal-modal__actions .btn.btn--subtle {
    background: #FFFFFF;
    border: 2px solid var(--color-gold);
    color: var(--color-navy);
    border-radius: 10px;
    padding-top: 8px;
    padding-bottom: 8px;
    font-size: 13px;
    font-weight: 700;
    /* S245 row 66 (Rob, the 7th of October 2026, on the gallery Delete button and the confirmation's No button: "on hover they only lose their border; they must pop like every button").
       MEASURED LIVE (real pointer states forced through the browser's own cascade) on example_oliver_hartnell's gallery, the viewer's Delete and the "Delete this photo?" pair: the viewer's
       Delete already pops (the unscoped `.btn.btn--danger:hover` rules at page-polish.css 10774 to 10809 and the OK beside it: wash .12, ring kept, lift -1px, the one shadow), so that half is done. This button, the
       Cancel, kept its ring on hover now but had no lift and no shadow at all (box-shadow none at rest, none hovered, transform none), and pressed it fell to Seeko's grey #eee with a
       transparent ring (the `.btn:not([disabled]):not(.disabled):active` rule had no answer here). It now carries the ONE shadow at rest (--shadow-gold-hover, as OK beside it, S245 row 130:
       a pair carries it from rest), lifts one pixel on a real pointer, and is held as the darker cream with its ring and no shadow (the 43.4.1 held state). Its white face and the hover colour are
       Rob's (S227 item 58) and are unchanged. */
    box-shadow: var(--shadow-gold-hover);
    transition: background-color 120ms ease-out, box-shadow 120ms ease-out, transform 120ms ease-out;
}
@media (hover: hover) {
.gal-modal__actions .btn.btn--subtle:hover {
    background: var(--color-cream-hover, #FFF5CC);
    color: var(--color-navy);
    border-color: var(--color-gold);
    box-shadow: var(--shadow-gold-hover);
    transform: translateY(-1px);
}
}
.gal-modal__actions .btn.btn--subtle:not([disabled]):not(.disabled):active {
    background: var(--color-cream-hover, #FFF5CC);
    border-color: var(--color-gold);
    color: var(--color-navy);
    box-shadow: none;
}
/* end of 60.1 */

/* On-brand toast (replaces native alert). */
.gal-toast {
    position: fixed;
    left: 50%;
    bottom: 24px;
    transform: translate(-50%, 20px);
    z-index: 310;
    /* S245 row 67 (Rob, the 7th of October 2026, on the gallery upload notice: "a blue bar in the wrong style (light cream, gold text, gold border)"; D-784: "the site's notice look (light
       cream fill, gold text, gold border, never a blue bar)"). MEASURED LIVE with the toast's own markup placed in the page: the fill was navy (--color-navy) with cream text. Light cream is
       --color-cream (#FFFBE6, the cream every cream button and the Spotify note's Got it use), the text --color-gold (#CC9900), and the border was already the 1.5px gold below. The words
       are the code lane's (T-S243-020). The error variant keeps its own dark red fill and its cream text (set explicitly below, since the text colour is no longer inherited from here). */
    background: var(--color-cream);
    color: var(--color-gold);
    padding: 12px 20px;
    border-radius: var(--radius-pill);
    border: 1.5px solid var(--color-gold);
    box-shadow: var(--shadow-md);
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 13.5px;
    max-width: 90vw;
    text-align: center;
    opacity: 0;
    transition: opacity .2s var(--ease-out), transform .2s var(--ease-out);
}
.gal-toast.is-open { opacity: 1; transform: translate(-50%, 0); }
.gal-toast--error { background: #8B1F1F; border-color: #CC9900; color: var(--color-cream); }

/* Mobile selection bar — stack count + actions + close so 2 selected doesn't render as vertical text. */
@media (max-width: 600px) {
    .selection-bar {
        display: flex;
        flex-wrap: wrap;
        gap: var(--sp-md);
        padding: var(--sp-md);
    }
    .selection-bar__count {
        flex: 1 1 100%;
        text-align: center;
        order: 0;
    }
    .selection-bar__actions,
    .selection-bar > .selection-bar__btn {
        flex: 0 0 auto;
        margin-inline: auto;
        order: 1;
    }
    .selection-bar__close {
        position: absolute;
        top: 8px;
        right: 12px;
        order: 2;
    }
    .selection-bar { position: relative; }
}

/* Mobile — checkbox always visible (no hover on touch screens). */
@media (max-width: 768px) {
    .photo-card__check { opacity: 1; }
}

/* end of 60 */

/* =========================================================================
   §61 Public profile — narrow-viewport widget layout.

   The customise workspace stores each widget's size as a grid-column span
   (w) and grid-row span (h). At desktop, the 12-column grid renders each
   widget at `w * column-width` wide. Below ≈1024px the grid columns shrink
   proportionally and widgets shrink with them — Rob's complaint: at 360px
   the sigil widget became a 20px circle.

   Fix: below 1024px, switch the container to flex-wrap and give every widget
   a FIXED pixel size derived from --w and --h (emitted inline by PHP in
   profile-system.php at the public-profile widget render). Reference cell
   = 80px wide × 10px tall, gap = 10px both axes — matches the typical
   desktop customise grid cell so widgets render at the same size users
   designed at. They wrap to new rows responsively to fill space.
   ========================================================================= */
/* S219 (D-506, Rob 10/09/26; T-S216-071): the flex-wrap fallback above is RETIRED. A width is now either
   designed by the member, and renders on the real grid exactly as designed, or not designed, and shows only
   the notice card. The grid keeps the same 48 columns, gap and row pitch it uses from 1024 up
   (profile-editor.css .profile-grid, the variables set by the public breakpoint script), so a public unit
   equals an editor unit at every width (measured within 0.03 percent, results/s219/grid1). */
@media (max-width: 1023px) {
  .profile-grid-public {
    display: grid !important;
    flex-wrap: nowrap !important;
    justify-content: normal !important;
    gap: var(--uks-grid-gap, 10px) !important;
    grid-auto-rows: var(--uks-grid-row, 10px) !important;
    grid-template-columns: repeat(48, minmax(0, 1fr)) !important;
    grid-template-rows: none !important;
  }
  .profile-grid-public > .profile-widget,
  .profile-grid-public > .profile-widget-public {
    width: auto !important;
    max-width: none !important;
    min-height: 0 !important;
    height: auto !important;
    flex: initial !important;
  }
}

/* end of 61 */

/* =========================================================================
   §62 Attendance page — design-agent port (Attendance.html, 2026-06-17)

   Ported VERBATIM from design bundle uksocials-club-handoff
   (api.anthropic.com/v1/design/h/8W5yTig_qmIQ62_Gc1F2lw),
   `project/attendance.css`. Tokens (--color-*, --sp-*, --radius-*, --font-*,
   --shadow-*, --duration-*, --ease-*), workspace shell (.workspace,
   .workspace__header, .workspace__title, .workspace__subtitle), the
   rep-subtitle-wrap + rep-header-rule pair, and the .btn/.btn--primary/
   .btn--danger family are all already present on live from §42 (Account),
   §58 (Reputation), and the universal button system — no token duplication
   needed.

   Markup emitted by event_system_attendance_bp_content()
   (mu-plugins/event-system.php §6.1.14, rewritten S107-001 17/06/26).
   ========================================================================= */

/* ── Stats row ───────────────────────────────────────────────────────────── */
.att-stats {
  display: flex;
  gap: var(--sp-md);
  margin-bottom: var(--sp-xl);
}
.att-stat {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: var(--sp-lg);
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: var(--sp-xl) var(--sp-lg);
  box-shadow: var(--shadow-sm);
}
.att-stat--muted { opacity: 0.55; }
.att-stat--cancelled {
  border-color: rgba(196, 28, 28, 0.25);
  background: var(--color-error-bg);
}
.att-stat__circle {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  border: 2px solid var(--color-gold);
  background: var(--color-surface);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 12px rgba(0,0,0,0.15);
  flex-shrink: 0;
  /* Shift circle up to align its geom centre with the label pill's cap-centre.
     Label pill ("Confirmed" / "Cancelled") cap-centre sits ~0.8px above circle
     geom centre at align-items:center; -2px via 0.5x margin/line-box rule. */
  margin-top: -2px;
}
.att-stat--cancelled .att-stat__circle {
  border-color: var(--color-error);
  box-shadow: 0 2px 12px rgba(196,28,28,0.1);
}
.att-stat__num {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 28px;
  line-height: 1;
  color: var(--color-navy);
  letter-spacing: -0.02em;
}
.att-stat--cancelled .att-stat__num { color: var(--color-error); }
.att-stat__label {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-navy);
  background: var(--color-cream);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-pill);
  padding: 4px 14px;
  white-space: nowrap;
}
.att-stat--cancelled .att-stat__label {
  color: var(--color-error);
  border-color: var(--color-error);
  background: var(--color-error-bg);
}
/* S234 21/09/2026, Rob on a phone screenshot of the Attendance tab: "The attendance counters
   don't need to be that far apart". They were three equal grid tracks across the whole card, so
   Attended sat at the far left, Cancelled at the far right and Not attended alone in the middle,
   with the distance between them set by the card width rather than by anything considered. The
   three are one group now: a centred row with a fixed 24px between them, the same grouped-and-
   centred reading as the CONFIRMED / PENDING / TOTAL trio on the profile stats widget, and it
   holds at every width because nothing here depends on the width any more. The card itself, the
   circles, the numbers and the labels are untouched. */
.att-stats {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: flex-start;
  gap: 24px;
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: 16px 8px;
  box-shadow: var(--shadow-sm);
}
/* The owner sees three counters instead of one. They are laid out by the row above now, so this
   modifier no longer needs a column track of its own; it stays as the hook the markup emits. */
.att-stats--owner { justify-content: center; }
.att-stats .att-stat {
  min-width: 0;
  /* The base .att-stat is flex:1, which is what stretched each counter to a third of the card. */
  flex: 0 0 auto;
  border: 0;
  box-shadow: none;
  background: transparent;
  padding: 0 2px;
  flex-direction: column;
  gap: 7px;
}
.att-stats .att-stat__circle { width: 40px; height: 40px; margin-top: 0; }
.att-stats .att-stat__num { font-size: 18px; }
.att-stats .att-stat__label {
  font-size: 9px;
  line-height: 1.25;
  letter-spacing: 0.04em;
  white-space: normal;
  text-align: center;
  border: 0;
  background: transparent;
  padding: 0;
}

/* ── Privacy toggle ──────────────────────────────────────────────────────── */
.att-privacy {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-sm);
  margin-bottom: var(--sp-xl);
  text-align: center;
}
.att-privacy .btn {
  border-radius: var(--radius-pill);
  max-width: 100%;
  white-space: normal;
  text-align: center;
  height: auto;
  line-height: 1.4;
  padding-top: 10px;
  padding-bottom: 10px;
}
/* "Hide" action = green invitation
   Scope-bumped to #buddypress .workspace ... + !important to defeat §42's
   `#buddypress .workspace .btn.btn--primary` (1,3,0 with !important) which
   sets cream/gold/navy. Design's rule body is unchanged — only the selector
   and importance escalate, per design-implementation skill §Theme/framework
   cascade conflicts. */
#buddypress .workspace .att-privacy .btn:not(.att-privacy__btn--on) {
  background: var(--color-surface) !important;
  border-color: var(--color-gold) !important;
  color: var(--color-navy) !important;
}
#buddypress .workspace .att-privacy .btn:not(.att-privacy__btn--on):hover {
  background: var(--color-cream) !important;
  border-color: var(--color-gold) !important;
}
/* "Hidden" active state = red warning
   Scope-bumped to match §42 `#buddypress .workspace .btn.btn--primary`
   specificity (1,3,0). Design's rule body unchanged. */
#buddypress .workspace .att-privacy .btn.att-privacy__btn--on {
  background: var(--color-error-bg) !important;
  border-color: var(--color-error) !important;
  color: var(--color-error) !important;
  box-shadow: none !important;
}
#buddypress .workspace .att-privacy .btn.att-privacy__btn--on:hover {
  background: rgba(196,28,28,0.12) !important;
  border-color: var(--color-error) !important;
  transform: translateY(-1px);
}
.att-privacy__note {
  font-size: 13px;
  color: var(--color-text-secondary);
  margin: 0;
}

/* ── Sections ─────────────────────────────────────────────────────────────── */
.att-section {
  overflow-anchor: none;
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: var(--sp-xl) var(--sp-2xl);
  box-shadow: var(--shadow-sm);
  margin-bottom: var(--sp-xl);
}
.att-section__head {
  margin-bottom: var(--sp-lg);
  text-align: center;
}
/* `font-size: 18px` carries !important to defeat profile-editor.css's
   `body.profile-dashboard-active #item-body .col-inner h2 { font-size: 22px }`
   (specificity 1,2,2). Scope-bump alone loses on class count. Design's rule
   body is otherwise verbatim. */
#item-body .att-section__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 18px !important;
  color: var(--color-navy);
  margin: 0 0 var(--sp-xs);
  display: inline-flex;
  align-items: center;
  gap: var(--sp-sm);
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-pill);
  padding: 6.5px 24px 5.5px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.12), var(--shadow-sm);
}
.att-section__hints {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: var(--sp-sm);
}
.att-section__hint {
  font-size: 13px;
  color: var(--color-text-secondary);
  margin: 0;
  line-height: 1.5;
}
.att-section__hint--sub {
  font-size: 12px;
  color: var(--color-text-muted);
  font-style: italic;
}

/* ── Section count bubble ────────────────────────────────────────────────── */
.att-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--color-cream);
  color: var(--color-navy);
  border: 1.5px solid var(--color-gold);
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 11px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  flex-shrink: 0;
  /* S229 16/09/26 (T-S229-059), Rob: "the number is way off the center of the circle, it's
     really low and left... use your overlays and measure it properly". MEASURED at dpr 8 on
     /attendance/ at 360, painted rows only: the gold ring's ink centres on 450.125 and the
     digit painted at 452.125, so 2.000px low, and 0.188px left. line-height:1 was letting the
     line box sit low; at 18px the digit paints 446.250 to 454.000, centre 450.125, dead on the
     ring, and the 0.375px left padding takes the horizontal to within 0.06px. Padding alone
     could not do it: the glyph rasterises on whole rows here, so it jumped 452.125 to 449.125
     with nothing in between. */
  line-height: 18px;
  padding-left: 0.375px;
  /* S227 item 44: measured at dpr 8, the digit's cap band sat 1.50px ABOVE the bubble's
     centre with padding-top:1px, at both the 18px and the 20px bubble. 4px puts the line
     box where the cap band lands on the centre: 0.00px at 360, 768 and 1280. */
  padding-top: 4px;
  padding-bottom: 0;
  /* Title text (18px) is taller than the bubble; `align-items: center` puts the bubble
     at the line-box centre but the title's visible-text caps sit higher in the line-box,
     so the bubble reads as low. Per pixel-scan rule, -3px lands the bubble geom centre
     within 0.1px of the title's visible cap centre. See /design-implementation pixel-scan rule. */
  /* S227 item 44: -3px lifted the bubble 1.50px above the pill's centre and 1.00px above the
     title's cap centre. With the title now centred, -1px lands the bubble on both. */
  margin-top: -1px;
}
.att-section__title .att-count {
  box-sizing: border-box;
  display: inline-grid;
  place-items: center;
  /* S245 row 133: padding 1px top and 0 bottom, as .rep-badge__count (the digit's line box now starts 5px below the ring's top at 20px and 4px
     below at the 18px size, whole numbers, where it started 4.5px and 3.5px below). MEASURED: with padding 0 the digit sat 0.94px high at half of
     all page positions (the Accepted Invitations badge at 1280 and the Upcoming Events badge at 360 on the test account); now 0.06px to 0.13px low everywhere. */
  padding: 1px 0 0;
  /* S245 row 133: the badge shares the heading text's baseline. The heading text is the taller item (a 21.6px line), so it starts on the pill's own
     padding and the badge is placed from it by whole pixels; centred in that line the ring was snapped differently from the heading text at
     different page positions: it sat 0.44px below the middle of the capitals at 4 of 20 positions and 1.44px below at 16 of 20 on the test account.
     Now 0.44px at every position at 1920, 1280, 768, 600 and 500 wide. The 480 and under block below puts it back to centre: there the heading can wrap
     to two lines and the badge is centred on both. */
  align-self: baseline;
  line-height: 1;
  margin-top: 0;
  transform: none;
}

/* ── Section empty state ─────────────────────────────────────────────────── */
.att-empty-state {
  text-align: center;
  padding: var(--sp-lg) var(--sp-xl);
}
.att-empty-state__glyph {
  font-size: 48px;
  line-height: 1;
  margin: 0 auto var(--sp-lg);
  text-align: center;
}
.att-empty-state__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 16px;
  color: var(--color-navy);
  margin-bottom: var(--sp-xs);
}
.att-empty-state__hint {
  font-size: 13px;
  color: var(--color-text-secondary);
  line-height: 1.6;
  text-wrap: pretty;
  margin: 0;
}
/* R3-23 (Rob, 24/09/2026): the call to action under an empty-state sentence is the standard
   button on its own row below the text, centred, never a link inside the sentence. */
.att-empty-state__cta {
  display: flex;
  justify-content: center;
  margin-top: var(--sp-lg);
}
.att-link {
  color: var(--color-gold-dark);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1.5px;
}
.att-link:hover { color: var(--color-gold); }

/* ── Reservation cards grid ──────────────────────────────────────────────── */
.att-res-grid {
  overflow-anchor: none;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--sp-lg);
  /* Cards keep their natural size; needed so the JS height-lock during
     pagination scroll doesn't stretch the visible cards. */
  align-content: start;
}
/* Odd card centring — `:last-child` is unreliable here because the live keeps
   page-2 cards in the DOM (hidden via display:none). The pagination JS adds
   `.att-res-card--page-last` to the last visible card when the page has an
   odd count, and this rule centres it. `:only-child` still covers the
   one-card-total case (no pagination).
   S244 row 126 (Rob 08/10 ~19:0x: "there are two columns and the second row is left aligned, but that's against the styling of the site. It
   should be centered."): that JS only runs for a section with MORE than five cards (the pager is only printed then, event-system.php 4199 and
   4498), so a plain three-card Events Attended grid never got the class and its third card sat left: measured by painted pixels on the live
   page, 186.5px left of the grid's centre at 1280, 207.5px at 1024, 159.5px at 768. A section with no pager holds no hidden cards, so there
   :last-child:nth-child(odd) is exact and centres the lone card by CSS alone; :not(:has(.att-pagination)) keeps this off every paged section
   (the Event Invites panel prints a pager too, its hidden cards are the other tabs), where the JS class above stays in charge. Same body for both grids. */
.att-res-grid > .att-res-card:only-child,
.att-res-grid > .att-res-card.att-res-card--page-last,
.att-section:not(:has(.att-pagination)) .att-res-grid > .att-res-card:last-child:nth-child(odd) {
  grid-column: 1 / -1;
  justify-self: center;
  width: calc(50% - var(--sp-lg) / 2);
}
.att-res-card {
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: var(--sp-xl);
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  gap: var(--sp-lg);
  /* Fixed min-height — keeps pages stable when event-name length (1 vs 2 lines)
     or date row presence vary. */
  min-height: 159px;
  transition: transform var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out);
}
.att-res-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-gold-hover);
}
.att-res-card__top {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-xs);
  text-align: center;
}
.att-res-card__name {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 16px;
  color: var(--color-navy);
  text-decoration: none;
  line-height: 1.3;
}
/* Also set color — Seeko's `a:hover { color: gold-dark }` would otherwise turn it gold. */
.workspace .att-res-card__name:hover { text-decoration: none; color: var(--color-navy); }
.att-res-card__when {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-xs);
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 13px;
  color: var(--color-text-secondary);
}
/* S207 05/09/26 (visual item 13): the "Were you there?" confirm card rendered its intro in black, left-aligned, and its
   stored-state line ("Noted, marked as not attended.") in grey, beside navy centred cards. Rob: "More black text and incorrect
   formatting/layout of that text". Everything in the confirm section is navy and centred like its neighbours. */
.att-section--confirm .att-confirm__intro { color: var(--color-navy); text-align: center; max-width: 560px; margin: 0 auto var(--sp-lg); line-height: 1.55; }
.att-section--confirm .att-confirm-card__actions, .att-section--confirm .att-confirm-card__actions * { color: var(--color-navy); }
.att-section--confirm .att-confirm-card__actions { justify-content: center; text-align: center; }
/* S244 row 125 (Rob 08/10 ~19:0x: "I marked one event as attended on the left, and then I marked the one on the right as not attended and the
   panel doubled in size to get all that extra text in, but at the same time it doubled the other panel on the left. So they both just jumped in size
   and that's really poor."). Two faults, measured live (Attendance, Were you there?, two cards side by side, both answered as the page's own settle() does):
   1. the answer is <span class="att-confirm-card__done"> (event-system.php 4653) and nothing styled it, so the server's long sentence printed at the
      BODY size, 18px Nunito Sans 400 on a 28.8px line, and the answered card went from 159px to 214.98px. It now takes the card's own text style,
      the date line's (.att-res-card__when above: Montserrat via --font-heading, 600, 13px, the inherited 1.6 line), centred and navy by the rules above.
   2. .att-res-grid lets its items stretch, so the card beside the answered one was stretched to the same 214.98px and "jumped" too. Cards in this
      section now keep their own height (align-items: start). Only this grid: the Upcoming and Accepted grids still match their rows. */
.att-confirm-card__done {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 13px;
}
/* S245 row 134 (Rob, the 9th of October 2026, on the finished-event cards of "Were you there?": "Let's make the date gold see what that looks like"). MEASURED live on
   example_aaron_fitzgerald's card: the date line is .att-res-card__when, rgba(3, 27, 131, 0.75) in Montserrat 600 at 13px, the one rule the dates of every Attendance card
   share, so the gold is scoped to the finished-event cards alone through the data-att-confirm-card attribute only those cards carry (event-system.php, the Were you there?
   loop); the "Did they make it?" card carries data-att-peer-card instead and keeps its date as it was. The gold is the site's --color-gold (#CC9900), the value the
   "Visibility:" label on this page's Events Attended cards already uses (.att-vis__label), so no new colour enters the site. */
.att-confirm-card[data-att-confirm-card] .att-res-card__when {
  color: var(--color-gold);
}
.att-section--confirm .att-res-grid { align-items: start; }
.att-res-card__foot {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-md);
  padding-top: var(--sp-lg);
  border-top: 1px solid rgba(204, 153, 0, 0.35);
  /* Push foot to the bottom of the card so the gold spacer + chip + cancel
     sit at the same vertical position regardless of title line count. */
  margin-top: auto;
}

/* Member Events tab: the approved Variation B small business-card format. */
/* S245 A22 (T-S221-022, 09/10/2026): the Variation B values the first build did not copy, read off
   card_variations.html (git 42427cb4, #varB) and measured beside the live card with getComputedStyle: the card's
   own two-layer navy shadow (.card); the sub lines at 13px, 2px under the line above (.sub); every line in the
   sheet's body font, Nunito Sans (--font-body), at its regular weight and in its navy ink; each fact line 10px
   under the line above (the facts paragraph); and the lines as plain paragraphs, as the sheet's <p> are, so a long
   line wraps as one sentence and no 4px flex gap is added between lines. The 12.5px fact size and the .8 and .85
   opacities were already the sheet's. Line heights stay the site's own: the sheet sets none. */
.att-place-card {
  padding: 0;
  overflow: hidden;
  flex-direction: row;
  gap: 0;
  min-height: 0;
  border: 2px solid var(--color-gold);
  border-radius: 16px;
  box-shadow: 0 2px 0 rgba(3, 27, 131, .10), 0 8px 20px rgba(3, 27, 131, .10);
}
.att-place-card__spine {
  width: 84px;
  flex: 0 0 84px;
  background: linear-gradient(160deg, var(--color-navy), #0a2ca0);
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 14px 0;
  gap: 10px;
}
.att-place-card__sigil {
  width: 58px;
  height: 58px;
  border-radius: 50%;
  background: linear-gradient(145deg, #041d88, #0a2a9e);
  border: 3px solid var(--color-gold);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-gold);
}
.att-place-card__tier {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 10px;
  letter-spacing: .12em;
  color: var(--color-gold);
}
.att-place-card__body {
  flex: 1;
  min-width: 0;
  padding: 14px;
  text-align: left;
}
.att-place-card__top {
  align-items: flex-start;
  text-align: left;
  gap: 0;
}
.att-place-card__name { font-size: 17px; }
.att-place-card__sub,
.att-place-card__fact {
  display: block;
  text-align: left;
  font-size: 12.5px;
  font-family: var(--font-body);
  font-weight: 400;
  color: var(--color-navy);
}
.att-place-card__sub { opacity: .8; font-size: 13px; margin-top: 2px; }
.att-place-card__fact {
  margin-top: 10px;
  opacity: .85;
}
.att-place-card__actions {
  justify-content: flex-end;
  gap: 8px;
  margin-top: 12px;
  padding-top: 0;
  border-top: 0;
}
/* S245 A22 (T-S221-022, 09/10/2026): the place card's buttons stay inside its text column. At 360 the column is
   128.5px wide (a 244.5px card less its two 2px borders, the 84px spine and the body's 14px padding each side) and
   .btn-dashboard (43.2) never wraps, so the 139.9px Cancel RSVP button ran out of the column to the left and 29.5px
   over the navy spine (measured live on example_harvey_blake's Events tab). It now takes at most the column's width
   and its label wraps inside it, as a Variation B button label can (card_variations.html: its .btn sets no nowrap).
   From 480 up every button fits on one line, so nothing moves there. !important on white-space only because 43.2
   sets nowrap with !important; 43.2 itself is unchanged for every other dashboard button. */
.att-place-card__actions > .btn-dashboard {
  max-width: 100%;
  white-space: normal !important;
}

/* ── Status chips ─────────────────────────────────────────────────────────── */
.att-chip {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 5px 12px;
  border-radius: 10px;
  white-space: nowrap;
  border: 1.5px solid transparent;
}
.att-chip--reserved { background: var(--color-cream); color: var(--color-navy); border-color: var(--color-gold); }
.att-chip--ticket   { background: var(--color-success-bg); color: var(--color-success); border-color: var(--color-success); }
.att-chip--waitlist { background: var(--color-warning-bg); color: var(--color-warning); border-color: var(--color-warning); }
.att-chip--btn {
  cursor: pointer;
  transition: filter var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-out);
  /* Design source had `font-family: inherit` here which made the chip pick up
     the live body font (Muli) instead of Montserrat — making the green text
     render lighter (thinner strokes) than the Hide-attendance button next to it.
     Force back to heading font so all variant colours render at the same weight. */
}
/* Hover pattern matches the rest of the site: bg goes light → slightly darker,
   + translateY(-1px) lift. Same shape as .btn--primary:hover (cream → cream-hover).
   For ticket/waitlist variants we double the alpha (0.08 → 0.16) to get the same
   visible "light → darker" step the cream variant gets. Each rule sets bg + color
   + border-color so Seeko's button:hover (which would set color: black + border: transparent)
   is fully neutralised — see standing-brief Rule 11. */
.workspace .att-chip--reserved:hover {
  background: var(--color-cream-hover);
  color: var(--color-navy);
  border-color: var(--color-gold);
  transform: translateY(-1px);
}
.workspace .att-chip--ticket:hover {
  background: rgba(39, 166, 68, 0.16);
  color: var(--color-success);
  border-color: var(--color-success);
  transform: translateY(-1px);
}
.workspace .att-chip--waitlist:hover {
  background: rgba(217, 119, 6, 0.16);
  color: var(--color-warning);
  border-color: var(--color-warning);
  transform: translateY(-1px);
}
.workspace .att-chip--btn:active { transform: translateY(0); }
/* S245 row 130 (Rob, the 9th of October 2026, on the Attendance cards: the buttons in an Upcoming Events card (the Reserved pill, Cancel) and in an invited-event card (the Accepted and
   Ticket pills, Request a refund) "they need to match the other buttons that they're with, fully, not just partly"). MEASURED live on example_aaron_fitzgerald's Upcoming Events card and
   example_jamal_osei's invited card: the foot's button (Cancel, or Request a refund) carries the one shadow, `0 4px 12px rgba(0,0,0,.16)` (--shadow-gold-hover, the .btn--danger and
   .btn--primary rest shadow, D-640 and D-655; the signed-off dashboard buttons carry the same at rest and hovered), and the status pills beside it, which take the button's box
   (S244 row 123) and its hover lift, had NONE. They carry it now, at rest and hovered, in the card foot only (the Event Invites tab's own foot, .ei-foot, is left as it was), and held
   down a pill takes the same look as the button beside it, no shadow and no lift (MEASURED live: a held pill kept its hover, the lift and, now, the shadow, while the Cancel beside it
   flattened). Each pill keeps its own ground: the cream of Reserved, the green wash of Ticket and Accepted. */
.workspace .att-res-card__foot:not(.ei-foot) .att-chip {
  box-shadow: var(--shadow-gold-hover);
}
.workspace .att-res-card__foot:not(.ei-foot) .att-chip:active {
  box-shadow: none;
  transform: none;
}

/* Chip is a <button> — Seeko's `button { margin-bottom: 1rem }` (18px) breaks
   flex-centring against the cancel button (S89 pattern). Also Seeko forces
   border-width:1px, so scope-bump to restore the spec's 1.5px.
   min-width + justify-content unifies Reserved / Waitlist / Ticket widths so
   the card foots read symmetrically.
   S244 row 123 (Rob 08/10 ~18:5x, on an Upcoming Events card: "The cancel button is m bigger and more prominent than the other buttons. The
   other buttons are showing a state ... but they should still just be normal status pills."): ONE pill size for everything in a card foot, the
   status chips (Reserved, Ticket, Accepted, Waitlist) and the Cancel / Request a refund button beside them, so the box is one rule for both.
   min-width was 86px, set when Reserved was the widest chip at 84.83px. Measured live on the 9th of October 2026 Reserved is 91.61px and Accepted
   91.80px, so 86px only ever stretched Ticket and the pills came out three widths (Cancel 94.33px). It is 96px, 4.2px above the widest label, so every
   pill is one width. The foot's button is taken out of .workspace .att-cancel-btn (below) and takes the chip's box here, value for value. */
.workspace .att-chip,
.workspace .att-res-card__foot:not(.ei-foot) .att-cancel-btn {
  border-width: 1.5px;
  margin-bottom: 0;
  min-width: 96px;
  justify-content: center;
  /* Asymmetric padding to push Montserrat caps to optical centre — caps render
     in the upper portion of the line-box, so symmetric 5/5 leaves text reading
     1px high. 6/4 shifts down 1px (0.5x line-box rule). Same fix as the cancel
     button's 5/3 asymmetric. See /design-implementation pixel-scan rule. */
  padding: 6px 12px 4px;
}
/* S244 row 123: the foot's button also takes the chip's type (.att-chip above: 11px, 0.06em, uppercase, the inherited 1.6 line, radius 10px), so
   its box is the chip's box to the pixel: 17.6px line + 6px + 4px padding + two 1.5px borders. Its red wash, ring and rest shadow stay the
   canonical .btn--danger / .btn--primary ones (42.8).
   S245 row 132 (Rob, the 9th of October 2026, on the invited-event card at 360: "The request the refund button overlaps the edges of the screen"). MEASURED live on
   example_jamal_osei's invited card with the paid-ticket markup placed in the page: .workspace .btn and Seeko's .btn both say white-space: nowrap, so the one-line label
   kept "Request a refund" 148.81px wide inside a foot only 96.5px wide at 360 (110px at 375, 143.31px at 412), where the 96px pills above it fit. The button spilled 26.2px
   past each side of the foot at 360, 12.2px of it over the navy spine. The label may now wrap and the button may not outgrow its column: max-width: 100% and
   white-space: normal, copied value for value from this page's own "Hide my attendance from other members" button (.att-privacy .btn, whose label wraps on a phone the
   same way; its text-align: center is already this button's). At 360 the button is 96.5px wide, the pills' column, and two lines tall; from 600 up (measured at 600, 768, 1024, 1280 and 1920)
   it still fits on one line and does not change (148.81px wide). */
.workspace .att-res-card__foot:not(.ei-foot) .att-cancel-btn {
  font-size: 11px;
  line-height: 1.6;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border-radius: 10px;
  max-width: 100%;
  white-space: normal;
}

/* ── Cancel button ───────────────────────────────────────────────────────── */
/* line-height: 1.6 matches the chip's inherited body line-height. Cancel has 2px
   border vs chip's 1px so its total padding is 2px less than chip's 5+5.
   Asymmetric padding (top/bottom 5/3, left/right 15/13) shifts text down 1px and
   right 1px to land dead-centre (each px of asymmetry shifts text by 0.5px). */
/* The Event Invites modal is relocated to <body> (escaping .workspace), so the
   .workspace-scoped shape can't reach its Accept/Decline buttons — match them too. */
/* S244 row 123: this rule is the Event Invites Accept and Decline buttons' shape (they sit in .ei-foot, and in #ei-modal below). The Upcoming
   Events card foot's own Cancel / Request a refund button shared the class and so took its 2px !important ring, 12px type and 7.5px 18px padding,
   which made it 94.33 x 31 beside chips of 91.6 x 29.6. The foot is taken out of this rule's scope by the :not(); :where() keeps the specificity at
   0,2,0 so nothing about the Invites buttons moves. The foot's button now takes the chip's box (the rules after .workspace .att-chip above). */
.workspace .att-cancel-btn:where(:not(.att-res-card__foot:not(.ei-foot) .att-cancel-btn)),
#ei-modal .att-cancel-btn {
  /* Match the visual weight of the Withdraw button on My Interests so Accept /
     Decline don't read as thin/light. Per Rob 28/06/26: 12px, bold, 2px border.
     Padding shifts text up 2px from the box centre to land dead-centre against
     the cap-band (measured: was +1px below; bumped to lift 2px). */
  /* S231 18/09/26 (triage item 20, Rob: the Decline label sits high). MEASURED by the painted
     CAP BAND, which is the right metric here because Accept carries a descender and Decline does
     not, so a full-ink reading makes them look different when they are not: both labels sat
     exactly 1.000px above the button centre. Each 1px of padding asymmetry moves text 0.5px, so
     the asymmetry goes from 1 to 3 and the labels land dead centre. The total stays 15px, so the
     button height does not change - Rob, S224: "Do not start changing button sizes now." */
  /* S231 18/09/26, second pass. Dead centre by cap band read LOW to Rob, which is the usual
     optical effect for a word with no descenders: the eye wants a cap-only label a shade above
     the geometric centre. His own S224 ruling names the amount - "I think it actually looked
     better when it was 0.5 pixel high" - so the asymmetry goes from 3 to 2 and the cap band
     sits 0.5px above centre. Total padding stays 15px, so the button height is unchanged. */
  padding: 7.5px 18px 7.5px 18px;
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border-width: 2px !important;
  border-radius: 10px;
}
/* S231 18/09/26 (triage item 17), Rob: "get on it with your overlays and measure the ink properly."
   MEASURED by decoding an 8x screenshot of the real button and finding the first and last rows that
   actually carry label ink: with symmetric padding the cap band sat 0.375px ABOVE the button centre
   and 0.313px LEFT of it. Padding cannot fix that here - LB-402: a sub-pixel `top` moves the layout
   box and not the paint, and these labels were bare text nodes with nothing to hang a rule on. They
   are now wrapped in span.ei-btn-label (invite-system.php 8.3.x) and moved by transform, which is
   the only thing that shifts painted text sub-pixel. Re-measured after deploying, not assumed. */
.ei-btn-label {
  display: inline-block;
  transform: translate(0.313px, 0.375px);
}
/* Seeko's `button:hover` zeroes border-color (and the workspace-scoped Accept
   hover at line 8671 can't reach the modal at body level). Restate the gold
   border on hover so the Accept pill keeps its ring. Per Rob 28/06/26. */
#ei-modal .ei-accept-btn:hover { border-color: var(--color-gold) !important; }

/* ── History cards grid ───────────────────────────────────────────────────── */
.att-hist-grid {
  overflow-anchor: none;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--sp-lg);
  align-content: start;
}
/* Same odd-card centring fix as att-res-grid above (S244 row 126: the third alternative is the one for a section with no pager). */
.att-hist-grid > .att-hist-card:only-child,
.att-hist-grid > .att-hist-card.att-hist-card--page-last,
.att-section:not(:has(.att-pagination)) .att-hist-grid > .att-hist-card:last-child:nth-child(odd) {
  grid-column: 1 / -1;
  justify-self: center;
  width: calc(50% - var(--sp-lg) / 2);
}
.att-hist-card {
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: var(--sp-xl);
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  /* Fixed min-height so page changes don't make the section jump as title length
     (1 vs 2 lines) and date row presence vary between events. 159px = the
     tall config (date row + 1-line title). */
  min-height: 159px;
  transition: transform var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out);
}
.att-hist-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-gold-hover);
}
.att-hist-card__top {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-xs);
  text-align: center;
  padding-bottom: var(--sp-lg);
}
.att-hist-card__spacer { flex: 1; }
.att-hist-card__name {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 15px;
  color: var(--color-navy);
  line-height: 1.35;
  text-align: center;
}
.att-hist-card__when {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-xs);
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 13px;
  color: var(--color-text-secondary);
}
.att-hist-card__foot {
  padding-top: var(--sp-md);
  border-top: 1px solid rgba(204, 153, 0, 0.35);
  display: flex;
  justify-content: center;
  /* Push foot to bottom — same reason as att-res-card__foot. */
  margin-top: auto;
}

/* ── Visibility custom dropdown ──────────────────────────────────────────── */
.att-vis {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-sm);
}
.att-vis__label {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 12px;
  color: var(--color-gold);
  white-space: nowrap;
  /* Align by CAP-CENTRE (not full visible glyph) — "Visibility:" has descenders
     (y, :) but "Public" doesn't, so full-glyph centring overshoots and lifts the
     label too high. Cap-centre alignment converges at 0 margin-top — the
     trigger's borders/padding already align both caps via align-items:center.
     Removing the negative margin entirely. See /design-implementation cap-centre note. */
  margin-top: 0;
}
.att-vis__wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
}
/* Scope-bumped to .workspace to beat Seeko's `button { padding: 0.5rem 1rem; margin-bottom: 1rem }`.
   Design has NO min-width/min-height — the old hack was leftover from a previous session and
   was making the trigger 54px tall (vs ~28px spec). */
/* SIZING ONLY. Colours + interaction (bg, border-color, color, --open
   navy-border + drop-shadow) are owned by §48 canonical .dropdown__trigger /
   .dropdown__trigger--open. Trigger emits both att-vis__trigger (JS hook /
   sizing) and dropdown__trigger (canonical styling) — see event-system.php
   §2.10. Only border-WIDTH stays here because canonical sets border-style +
   border-color via longhands. */
.workspace .att-vis__trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  border-width: 2px;
  border-radius: var(--radius-md);
  /* Asymmetric padding to optically balance the right-side dropdown arrow —
     symmetric 28/28 mathematically centres the text but the arrow's visual
     weight pulls the eye right, making text read off-centre. 24L/32R balances.
     S244 row 127 (Rob 08/10 ~19:0x: "the label 'public' is maybe a pixel too high - get the overlays on it"). MEASURED on the live page by the accepted
     overlay (s238_btn_label_overlay.py on an 8x capture of every trigger, the capital P against the painted gold ring): the label sat 0.814px ABOVE the
     ring's centre on all five triggers of Harvey's Attendance page. The box was 35.19px: the button's inherited 1.6 line (12px x 1.6 = 19.2px) plus 12px
     padding plus 4px of border, a fractional, even-looking height that no whole-pixel move can centre a label in (da.md 21b). line-height is now a whole 19px,
     so the box is 35px, an ODD height with a true middle row, and the 12px of vertical padding moves from 6/6 to 7 above and 5 below, which lowers the text one whole
     pixel (padding moves painted text in whole pixels only, da.md 9a) and leaves the box 35px. Re-measured the same way: 0.186px BELOW centre on all five. 0.814 up
     becomes 0.186 down, the nearest a whole-pixel step reaches (the next step down would be 1.186). The 24L/32R side padding is untouched. */
  padding: 7px 32px 5px 24px;
  line-height: 19px;
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 12px;
}
/* S245 row 136 (Rob, the 9th of October 2026, on S244-127: "the drop down arrows have not been centered as well as the label, so please centre those also and make them
   gold"). MEASURED by the painted ink (a clean element picture's own pixels with the accepted overlay) on all five triggers of example_harvey_blake's Attendance page at 8x,
   4x, 2x and 1x: the label's capital band sits +0.19px (8x) from the ring's centre, but the arrow's ink sat 0.5px HIGH on three triggers and 0.5px LOW on the other two (-0.53 and
   +0.47 at 2x, -0.41 and +0.59 at 1x). The arrow was placed with top: 50% of the 31px padding box (15.5px) and pulled up with translateY(-50%) (5.5px), a half pixel, and the
   browser resolved that half pixel up or down according to each trigger's own fractional place on the page: shifting the page by half a pixel swapped the high triggers and the
   low ones. The offset is now a whole pixel, (31px padding box - 11px arrow) / 2 = 10px, and the transform is gone (da.md 21b: a half-pixel offset has no pixel to land on), so
   the ring and the arrow snap together; re-measured at 8x, 4x, 3x, 2x, 1.5x, 1.25x and 1x, and with the page shifted by fractions of a pixel, the arrow's ink midpoint is within
   0.12px of the ring's centre on every trigger. Colour: the site's gold, --color-gold at full opacity, the value of the "Visibility:" label beside it (.att-vis__label) and of the
   ring (it was --color-navy at 0.6 opacity). */
.att-vis__arrow {
  position: absolute;
  right: 9px;
  top: 10px;
  color: var(--color-gold);
  opacity: 1;
  pointer-events: none;
  transition: transform var(--duration-fast) var(--ease-out);
}
/* Open: the chevron turns over about its own centre (the old translateY(-50%) went with the half-pixel offset above). */
.att-vis__arrow--open { transform: rotate(180deg); }
/* Default wrapper position so the absolute-positioned menu anchors to the trigger. */
.att-vis { position: relative; }
/* When the menu is OPEN (trigger has --open modifier), lift this wrapper above
   sibling cards so the popover doesn't get hidden behind the next card's
   stacking context. Only the currently-open one lifts. */
.att-vis:has(.att-vis__trigger--open) { z-index: 98; /* S245 row 35: 98, was 1000 (header is 99; see 26.5.7) */ }
/* Also lift the parent card while the menu is open so the popover can extend
   below the card without being clipped/overlapped by the next card. */
.att-hist-card:has(.att-vis__trigger--open),
.att-res-card:has(.att-vis__trigger--open) {
  position: relative;
  z-index: 98;                             /* S245 row 35: 98, was 1000 (header is 99; see 26.5.7) */
}

/* Menu container — matches the site's `.interest-reasons-popover` pattern (white bg,
   2px gold border, 12px radius, padding + gap between option panels). See
   interest-system.php §7.1.3 for the canonical pattern this is following. */
.att-vis__menu {
  position: absolute;
  top: calc(100% + 10px);                /* 10px gap from trigger, matches popover */
  left: 50%;
  transform: translateX(-50%);            /* horizontally centred under the trigger */
  min-width: 140px;                       /* narrower — centred text doesn't need 200 */
  background: #FFFFFF;
  border: 2px solid var(--color-gold);
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.18);
  padding: 14px;
  margin: 0;
  list-style: none;
  z-index: 98;                             /* S245 row 35: was 1000 to match the interest-reasons-popover stack; now one below the sticky header (z 99), see 26.5.7 */
  display: flex;
  flex-direction: column;
  gap: 8px;
}
/* SIZING ONLY. Colours + states are owned by §48 canonical .dropdown__option
   / .dropdown__option--selected. Markup emits both att-vis__option (JS hook
   + sizing) and dropdown__option (canonical styling). */
.att-vis__option {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  white-space: nowrap;
  padding: 8px 12px;
  border-width: 1.5px;
  border-radius: 8px;
  font-family: 'Nunito Sans', sans-serif;
  font-weight: 500;
  font-size: 13px;
  line-height: 1.2;
}

/* ── Pagination ──────────────────────────────────────────────────────────── */
.att-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-lg);
  margin-top: var(--sp-xl);
}
/* Scope-bumped to .workspace to beat Seeko's `button` rule (width:auto, padding:0.5rem 1rem,
   border:1px transparent, margin-bottom:1rem). Padding override is the important one —
   without it the button stretches to ~50px wide. */
/* D-640/D-651 (S235 SHADOWS-5, 25/09/26): was var(--color-surface) fill with no rest
   shadow; becomes the full standard button, as the brief for this group named it. */
.workspace .att-pagination__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  margin: 0;
  border-radius: 50%;
  border: 1.5px solid var(--color-gold);
  background: var(--color-cream);
  color: var(--color-navy);
  cursor: pointer;
  box-shadow: var(--shadow-gold-hover);
  transition: background var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-out);
}
.workspace .att-pagination__btn:hover:not(:disabled) { background: var(--color-cream); transform: scale(1.08); }
/* D-651: pressed carries no shadow, and there was no active rule at all here. The extra
   :not(:disabled) matches the class-count the Seeko theme own button active reset needs
   to be beaten on specificity alone, the same fix proven necessary at R3-11 (.cal__nav-btn). */
.workspace .att-pagination__btn:active:not(:disabled) { background: var(--color-cream-hover); box-shadow: none; }
.workspace .att-pagination__btn:disabled { opacity: 0.3; cursor: default; }
.att-pagination__info {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 13px;
  color: var(--color-navy);
}

/* ── Responsive ──────────────────────────────────────────────────────────── */
@container vp (max-width: 480px) {
  .att-res-grid  { grid-template-columns: 1fr; }
  .att-hist-grid { grid-template-columns: 1fr; }
  .att-res-grid > .att-res-card:last-child:nth-child(2n+1),
  .att-hist-grid > .att-hist-card:last-child:nth-child(2n+1) {
    width: 100%;
  }
  /* S245 A22: the place card keeps its own padding: 0, as in the @media twin below. */
  .att-res-card:not(.att-place-card)  { padding: var(--sp-lg); }
  .att-hist-card { padding: var(--sp-lg); }
}
/* Parallel @media for the live site — the design uses @container vp which
   only fires inside a `.viewport-frame` (design preview only). Live needs
   plain @media queries against actual viewport width. */
/* ATT-GRID (S238, the 29th of September 2026). The one-column rules stood in the 480px block below, so the grids kept two
   columns from 481px up. MEASURED on live (Attendance, example_harvey_blake): the grid is the screen less 139.5px, a
   reservation card cannot be narrower than 247.9px (250.4px with the Yes and No buttons) and a history card 207.2px,
   so two reservation cards need a grid of 512px, which the screen only gives from about 655px: at 600 the second card
   ran 51px past the grid, at 520 by 123px, the No button spilled out of its card, and the history cards ran 42px past.
   One column now holds up to 660px for both grids, so the two grids on the tab always change together. The same class
   draws the cards on Event Invites and My Events, read at seven widths with this rule: no card past its grid. */
@media (max-width: 660px) {
  .att-res-grid  { grid-template-columns: 1fr; }
  .att-hist-grid { grid-template-columns: 1fr; }
  .att-res-grid > .att-res-card:only-child,
  .att-res-grid > .att-res-card.att-res-card--page-last,
  .att-section:not(:has(.att-pagination)) .att-res-grid > .att-res-card:last-child:nth-child(odd),
  .att-hist-grid > .att-hist-card:only-child,
  .att-hist-grid > .att-hist-card.att-hist-card--page-last,
  .att-section:not(:has(.att-pagination)) .att-hist-grid > .att-hist-card:last-child:nth-child(odd) {
    width: 100%;
    grid-column: auto;
    justify-self: stretch;
  }
}
@media (max-width: 480px) {
  /* S245 A22 (T-S221-022, 09/10/2026): :not(.att-place-card). The Variation B place card sets its own padding: 0
     (.att-place-card, above) so its navy spine meets the gold border; this rule, later in the file at the same weight, gave it
     16px of padding back at 480 and below, so the spine sat 18px inside the card's outer edge instead of 2px
     (measured live at 480 and 360 on the Events tab cards and on the Attendance tab's Accepted Invitations cards,
     which share the shell). Every other card keeps this padding exactly. */
  .att-res-card:not(.att-place-card)  { padding: var(--sp-lg); }
  .att-hist-card { padding: var(--sp-lg); }
  /* Shrink section-title font so the pill + count bubble fits on one line at 360. */
  .att-section__title { font-size: 15px; padding: 5px 16px; }
  /* S245 row 133: centred again (a heading that wraps to two lines has the badge centred on both), and lifted one whole pixel: centred in the one-line
     heading's 24px line the ring sat 1.44px below the middle of the capitals at 16 of 20 page positions; lifted it is 0.44px below at 16 of 20 and 0.56px
     above at 4 of 20 (the digit 0.06px low of its ring at all 20). */
  .att-section__title .att-count { width: 18px; height: 18px; align-self: center; position: relative; top: -1px; }
}
@container vp (max-width: 600px) {
  /* S234 21/09/2026: this used to stack the three counters into a column on a narrow card. The
     counters are a centred group at every width now (see the rule above), and three of them fit
     a 360px card on one row, so the stacking rule is replaced by the wrap the row already allows. */
  .att-stats {
    flex-wrap: wrap;
  }
  .att-stat {
    flex-direction: row;
    align-items: center;
    justify-content: center;
    gap: var(--sp-lg);
    padding: var(--sp-lg) var(--sp-xl);
  }
  .att-stat__num { font-size: 22px; }
  .att-stat__circle { width: 48px; height: 48px; }
}

/* end of 62 */

/* =========================================================================
   §63 Wish List page — design-agent port (Wish List.html, 2026-06-19)

   Ported VERBATIM from design_handoff_wishlist/design/wishlist.css. Tokens
   (--color-*, --sp-*, --radius-*, --font-*, --shadow-*, --duration-*,
   --ease-*), the workspace shell (.workspace, .workspace__header,
   .workspace__title, .workspace__subtitle), and the .btn / .btn--primary
   family are already present from §42 (Account), §46 (Dashboard), and the
   universal button system — no token duplication needed.

   The @container vp queries use the cq root set up in §42.0 (#item-body).
   The @container wlc queries use .workspace itself as the container root
   (declared in this section's own .workspace rule below).

   Markup emitted by interest_wishlist_bp_tab_content() (mu-plugins/
   interest-system.php §14.3, rewritten S109 19/06/26).
   ========================================================================= */

/* =========================================================================
   Wish List — page-specific styles
   Tokens + chrome + workspace shell from styles.css.
   Section panels mirror the Attendance gold-panel system; cards are richer
   (category-tinted media, date badge, heart-toggle remove) so the page reads
   as a curated board of things the member wants to do — not a flat list.
   ========================================================================= */

/* ── Intro line under the page subtitle ──────────────────────────────────── */
.wl-summary {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-sm);
  margin: calc(-1 * var(--sp-md)) auto var(--sp-2xl);
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-navy);
  background: var(--color-cream);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-pill);
  padding: 7px 18px 6px;
  width: fit-content;
  line-height: 1;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
}
.wl-summary__dot {
  width: 4px; height: 4px; border-radius: 50%;
  background: var(--color-gold);
  flex-shrink: 0;
}

/* ── Section panel ───────────────────────────────────────────────────────── */
/* The gold panels are a CONSTANT width regardless of how many cards sit on
   them — every panel matches the widest layout that fits (3-up / 2-up / 1-up),
   so Events, Organisers and Venues line up edge-to-edge. The width is sized to
   the column count and set per breakpoint below; cards centre inside via the
   grid's auto-fit. The workspace is a query container (wlc) so the count tracks
   its REAL width — stable across the 1023px sidenav-collapse. */
.workspace {
  max-width: 992px;
  margin-inline: auto;
  container-type: inline-size;
  container-name: wlc;
}
.wl-section {
  overflow-anchor: none;
  --wl-panel-w: 970px;
  --wl-cols: 3;
  width: var(--wl-panel-w, 970px);
  max-width: 100%;
  margin-left: auto;
  margin-right: auto;
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: var(--sp-2xl) var(--sp-2xl) var(--sp-2xl);
  box-shadow: var(--shadow-sm);
  margin-bottom: var(--sp-xl);
}
.wl-section__head {
  text-align: center;
  margin-bottom: var(--sp-xl);
}
.wl-section__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 18px;
  line-height: 1;
  color: var(--color-navy);
  margin: 0;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-sm);
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-pill);
  padding: 7px 12px 7px 18px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12), var(--shadow-sm);
}
.wl-section__label {
  display: inline-flex;
  align-items: center;
  line-height: 1;
}
.wl-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--color-cream);
  color: var(--color-navy);
  border: 1.5px solid var(--color-gold);
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 11px;
  min-width: 22px;
  height: 22px;
  /* S245 row 133: the digit's line box must start a whole number of pixels below the ring's top (see .rep-badge__count): with 1px above and 1px
     below it started 5.5px below and the digit sat 0.81px to 0.94px high in five of the six Wish List badges measured on the live page (Events,
     Organisers and Venues at 1280 and at 360; only Events at 1280 was already right, by position). 2px above and 1px below starts it 6px below:
     0.06px to 0.13px low at every position and width. The bubble stays 22px by 22px,
     so the ink alignment script in interest-system.php (which only moves the bubble's top to a whole pixel) is unaffected. */
  padding: 2px 6px 1px;
  border-radius: var(--radius-pill);
  flex-shrink: 0;
  line-height: 1;
}

/* FF02-26: Organisers and Venues count badges use the same vertical padding
   as the other Wish List counts; the old asymmetric nudge made their numerals
   read high/low against the circle at phone scale. */
[data-wl-section="venues"] .wl-count,
[data-wl-section="organisers"] .wl-count {
  padding-top: 2px;
  padding-bottom: 1px;
}

/* ── Card grid ───────────────────────────────────────────────────────────── */
/* Cards hold a FIXED 290px width at every screen size. Flex-wrap + centre means
   EVERY row is centred — a full row fills the constant-width panel edge-to-edge,
   and a partial last row or a lone trailing card centres in its row (grid would
   leave an orphan stuck in the left column). align-content:flex-start is
   REQUIRED for the smooth-on-shrink height-lock (§10) — without it the locked
   height spreads the rows apart mid-animation. */
.wl-grid {
  overflow-anchor: none;
  --wl-card-w: 290px;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-content: flex-start;
  gap: var(--sp-lg);
}
.wl-grid--venues { /* same flex behaviour as .wl-grid */ }
/* A lone card sits at the same fixed width, centred (flex already centres). */
.wl-grid--solo {
  justify-content: center;
}

/* ── Event / venue card ──────────────────────────────────────────────────── */
.wl-card {
  flex: 0 0 var(--wl-card-w);
  width: var(--wl-card-w);
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  text-decoration: none;
  transition: transform var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out);
}
.wl-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-gold-hover);
  text-decoration: none;
}
.wl-card.is-removing {
  opacity: 0;
  transform: scale(0.94);
  transition: opacity var(--duration-normal) var(--ease-out),
              transform var(--duration-normal) var(--ease-out);
  pointer-events: none;
}

/* Category-tinted media block — echoes the Gallery tile language the member
   already knows (tinted bg, faint diagonal texture, centred glyph, watermark). */
.wl-card__media {
  position: relative;
  height: 132px;
  display: grid;
  place-items: center;
  background: var(--cat-bg, linear-gradient(135deg, #031B83, #0a2494));
  overflow: hidden;
  border-radius: 15px 15px 0 0;
}
.wl-card__media::before {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(45deg, rgba(255,255,255,0.05) 0 1px, transparent 1px 13px);
  pointer-events: none;
}
.wl-card__watermark {
  position: absolute;
  top: 9px; left: 0; right: 0;
  text-align: center;
  font-family: 'Courier New', monospace;
  font-size: 9px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255, 251, 230, 0.4);
  pointer-events: none;
}

/* Date badge — sits in the top-left corner of the media block on top of the
   image (S109 19/06/26 Rob — was top:118 overlapping media-body boundary). */
.wl-date-badge {
  position: absolute;
  left: var(--sp-md);
  top: var(--sp-md);
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-sm);
  padding: 5px 10px 4px;
  text-align: center;
  line-height: 1;
  box-shadow: 0 4px 8px rgba(2, 22, 106, 0.18);
  z-index: 2;
}
.wl-date-badge__day {
  display: block;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 19px;
  color: var(--color-navy);
}
.wl-date-badge__month {
  display: block;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-gold);
  margin-top: 2px;
}

/* Organiser Sigil — circular, sits where the date badge sits on event cards */
.wl-sigil-badge {
  position: absolute;
  left: var(--sp-md);
  top: 100px;
  width: 58px;
  height: 58px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 20px;
  letter-spacing: 0.02em;
  color: var(--color-gold);
  background: linear-gradient(135deg, #2a3556, #1f2848);
  border: 2.5px solid var(--color-gold);
  box-shadow: 0 4px 10px rgba(2, 22, 106, 0.28);
  z-index: 2;
}

/* Card body */
.wl-card__body {
  /* sp-sm top (was sp-xl) — halves the visible gap between the media block
     and the title text (Rob 19/06/26 v4). */
  padding: var(--sp-sm) var(--sp-lg) var(--sp-lg);
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--sp-sm);
  flex: 1;
  border-radius: 0 0 15px 15px;
}

/* Gold spacer rule — sits between the title and the meta rows on event
   cards (Rob 19/06/26 v2). Flex item in body flow now (was absolute in v1).
   Body's gap is sp-sm (8px); negative margin-top tightens the title→rule
   gap to ~7px (reduced by a third from the previous ~10px — Rob 19/06/26 v3). */
.wl-card__rule {
  align-self: center;
  flex-shrink: 0;
  width: 60%;
  height: 1.5px;
  margin: -1px 0 2px;
  background: var(--color-gold);
  border-radius: 1px;
  pointer-events: none;
}
.wl-card__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 16px;
  line-height: 1.3;
  color: var(--color-navy);
  margin: 0;
  text-wrap: balance;
  /* Reserve fixed space for up to 2 lines so the rule + content + button
     below sit at the SAME Y across every card in a row regardless of whether
     a title wraps to one or two lines (Rob 19/06/26). Centre-align the text
     within its reserved space so a one-line title doesn't look top-anchored. */
  min-height: 2.6em;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}
.wl-card__meta {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  padding-top: var(--sp-sm);
}

/* Reserve fixed height for the meta block so the button below sits at the
   SAME Y across every card in a row regardless of whether the meta has 1
   row (organisers/venues) or 2 rows (event venue + time). The values are
   the natural max-row height for each card type. Rob 19/06/26. */
[data-wl-section="events"] .wl-card__meta {
  min-height: calc(2 * 1.3em + 5px); /* 2 rows × line-height + 1 gap */
}
[data-wl-section="organisers"] .wl-card__meta,
[data-wl-section="venues"] .wl-card__meta {
  min-height: 1.3em; /* 1 row */
  /* +5px below to match the 5px inter-row gap baked into events' 2-row
     meta — without this, the last-row→button gap reads as 8px on org/ven
     vs 13px on events (Rob 19/06/26). */
  padding-bottom: 5px;
}
.wl-meta-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 13px;
  color: var(--color-text-secondary);
  line-height: 1.3;
}
.wl-meta-row svg {
  flex-shrink: 0;
  color: var(--color-gold);
}
.wl-meta-row span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Area / type pill on venue + event cards */
.wl-tag {
  align-self: center;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-navy);
  background: rgba(204, 153, 0, 0.12);
  border: 1px solid rgba(204, 153, 0, 0.5);
  border-radius: var(--radius-pill);
  padding: 4px 10px 3px;
  line-height: 1;
}

/* ── Interest toggle button (Show Interest / Interested ✓) ───────────────
   Everything on the Wish List is already saved, so the button shows its
   active "Interested" state and pins to the bottom-centre of every card,
   landing in the same spot regardless of card content. Hover reveals a
   clear "Remove" affordance. */
/* Scope-bumped to .workspace to defeat Seeko's `button { margin-bottom: 1rem }`
   which pushes the button up off the card's bottom edge. */
.workspace .wl-interest-btn {
  /* auto pushes the button to the card's bottom edge so every button in a
     row bottom-aligns regardless of how many lines the title/meta take.
     margin-bottom: 0 defeats the theme's 1rem default. */
  margin: auto 0 0;
  align-self: center;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 13px;
  line-height: 1;
  /* Optical vertical centring (DESIGN_RULES §9): measured live — with 6/9
     padding the text cap-centre sat 1.05px ABOVE the button centre, so the
     padding is rebalanced to 7 top / 8 bottom to drop the cap onto centre. The
     icon is nudged separately (below) onto the same cap line. */
  padding: 7px 16px 8px;
  border-radius: 10px;
  border: 2px solid var(--color-error);
  background: var(--color-error-bg, rgba(196, 28, 28, 0.06));
  color: var(--color-error);
  cursor: pointer;
  gap: 7px;
  box-shadow: none;
  transition: background var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out);
}
.workspace .wl-interest-btn:hover {
  background: rgba(196, 28, 28, 0.12);
  border-color: var(--color-error);
  color: var(--color-error);
  box-shadow: none;
}
.workspace .wl-interest-btn:focus,
.workspace .wl-interest-btn:active {
  background: var(--color-error-bg, rgba(196, 28, 28, 0.06));
  border-color: var(--color-error);
  color: var(--color-error);
  box-shadow: none;
}
.workspace .wl-interest-btn:active { transform: translateY(1px); }
.workspace .wl-interest-btn svg {
  display: block;
  width: 20px;
  height: 20px;
  stroke-width: 3;
  transform: translateY(0);
}
.workspace .wl-interest-btn__txt { line-height: 1; }
/* Inline placement for the horizontal organiser card */
.wl-interest-btn--inline {
  margin-top: 0;
  flex-shrink: 0;
}

/* ── Heart-toggle remove control ─────────────────────────────────────────── */
.wl-remove {
  position: absolute;
  top: var(--sp-sm);
  right: var(--sp-sm);
  z-index: 3;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: none;
  display: inline-grid;
  place-items: center;
  background: rgba(3, 27, 131, 0.45);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  color: var(--color-gold);
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-out);
}
.wl-remove svg { display: block; }
.wl-remove .wl-remove__heart { display: block; }
.wl-remove .wl-remove__x { display: none; }
.wl-remove:hover {
  background: var(--color-error);
  color: #fff;
  transform: scale(1.08);
}
.wl-remove:hover .wl-remove__heart { display: none; }
.wl-remove:hover .wl-remove__x { display: block; }
.wl-remove:active { transform: scale(0.96); }
/* Tooltip */
.wl-remove::after {
  content: "Remove";
  position: absolute;
  top: 50%;
  right: calc(100% + 8px);
  transform: translateY(-50%);
  background: var(--color-navy);
  color: var(--color-gold);
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 4px 9px;
  border-radius: var(--radius-sm);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--duration-fast) var(--ease-out);
}
.wl-remove:hover::after { opacity: 1; }

/* Remove control on the white organiser card (no media to sit over) */
.wl-remove--onlight {
  background: var(--color-cream);
  border: 1.5px solid var(--color-gold);
  color: var(--color-gold);
}

/* ── Organiser card ──────────────────────────────────────────────────────── */
.wl-org-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--sp-lg);
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: var(--sp-lg) var(--sp-xl) var(--sp-lg) var(--sp-lg);
  box-shadow: var(--shadow-sm);
  text-decoration: none;
  transition: transform var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out);
}
.wl-org-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-gold-hover);
  text-decoration: none;
}
.wl-org-card.is-removing {
  opacity: 0;
  transform: scale(0.94);
  transition: opacity var(--duration-normal) var(--ease-out),
              transform var(--duration-normal) var(--ease-out);
  pointer-events: none;
}
.wl-org-card__sigil {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  flex-shrink: 0;
  display: grid;
  place-items: center;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 22px;
  color: var(--color-gold);
  background:
    linear-gradient(145deg, #041D88, #0A2A9E) padding-box,
    linear-gradient(135deg, #CC9900, #E6B800, #CC9900) border-box;
  border: 3px solid transparent;
  box-shadow: 0 3px 12px rgba(0, 0, 0, 0.25);
}
.wl-org-card__body {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  flex: 1;
}
.wl-org-card__name {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 16px;
  color: var(--color-navy);
  line-height: 1.25;
}
.wl-org-card__meta {
  display: flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 13px;
  color: var(--color-text-secondary);
}
.wl-org-card__meta svg { color: var(--color-gold); flex-shrink: 0; }
.wl-org-card__badges { display: flex; align-items: center; gap: var(--sp-sm); margin-top: 2px; }

/* Tier badge (organiser) — matches styles.css tier-badge palette */
.wl-tier-badge {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 11px;
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 5px 12px 4px;
  border-radius: var(--radius-pill);
  color: var(--color-success);
  background: var(--color-success-bg);
}
.wl-following {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--color-navy);
  background: var(--color-cream);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-pill);
  padding: 3px 10px 4px;
}

/* ── Footer browse link ──────────────────────────────────────────────────── */
.wl-browse {
  display: flex;
  justify-content: center;
  margin-top: var(--sp-2xl);
}
.wl-browse a {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 14px;
  color: var(--color-gold);
  letter-spacing: 0.02em;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  text-decoration: none;
  transition: gap var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out);
}
.wl-browse a:hover { color: var(--color-gold-dark); gap: 10px; text-decoration: none; }

/* S229 16/09/26 (T-S229-058), Rob: "That's a bit better but still a tiny bit low. The arrow
   needs to go up just a little bit more." MEASURED at dpr 8 on the wish list at 360 from the
   painted gold rows: the label's cap band is 445.000 to 455.125, centre 450.062, and the arrow
   painted 450.000 to 453.875, centre 451.938, so 1.875px low. After: 450.062, dead on it. */
.wl-browse a span {
  display: inline-block;
  transform: translateY(-1.875px);
}

/* ── Full-page empty state (zero content) ────────────────────────────────── */
.wl-empty {
  text-align: center;
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  padding: var(--sp-4xl) var(--sp-2xl);
  max-width: 560px;
  margin: 0 auto;
}
.wl-empty__glyph {
  font-size: 52px;
  line-height: 1;
  margin-bottom: var(--sp-lg);
}
.wl-empty__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 22px;
  color: var(--color-navy);
  margin: 0 0 var(--sp-sm);
}
.wl-empty__hint {
  font-size: 15px;
  color: var(--color-text-secondary);
  line-height: 1.6;
  text-wrap: pretty;
  margin: 0 auto var(--sp-xl);
  max-width: 400px;
}

/* Per-section mini empty (when one group has been cleared) */
.wl-section__empty {
  text-align: center;
  padding: var(--sp-xl) var(--sp-lg);
  color: var(--color-text-secondary);
  font-size: 14px;
  line-height: 1.6;
}
.wl-section__empty strong {
  display: block;
  font-family: var(--font-heading);
  color: var(--color-navy);
  font-size: 15px;
  margin-bottom: 2px;
}

/* ── Pagination (mirrors the Attendance page) ────────────────────────────── */
.wl-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-lg);
  margin-top: var(--sp-xl);
}
/* Scope-bumped to .workspace to beat Seeko's `button` rule (width:auto, padding:0.5rem 1rem,
   border:1px transparent, margin-bottom:1rem). Mirrors the Attendance fix at §62. */
.workspace .wl-pagination__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  margin: 0;
  border-radius: 50%;
  border: 1.5px solid var(--color-gold);
  background: var(--color-surface);
  color: var(--color-navy);
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-out);
}
.workspace .wl-pagination__btn:hover:not(:disabled) { background: var(--color-cream); transform: scale(1.08); }
.workspace .wl-pagination__btn:disabled { opacity: 0.3; cursor: default; }
.workspace .wl-pagination__btn svg { display: block; }
.wl-pagination__info {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 13px;
  color: var(--color-navy);
}

/* ── Panel width tracks the workspace's REAL width (wlc container) ─────────── */
/* The panel is a constant width per breakpoint — same for every section — and
   auto-fit centres whatever cards are on it. 970 = 3-up, 664 = 2-up, 358 = 1-up
   (card grid + section padding/border). Driven off the workspace width so it's
   correct whether or not the sidenav is collapsed. */
@container wlc (max-width: 969px) {
  .wl-section { --wl-panel-w: 664px; --wl-cols: 2; }
}
@container wlc (max-width: 663px) {
  .wl-section { --wl-panel-w: 358px; --wl-cols: 1; }
}

/* ── Responsive (container query — driven by the Viewport tweak) ─────────── */
/* Card WIDTH is fixed (see .wl-grid) so the grid needs no column breakpoints —
   auto-fit handles the count. These queries only adjust section padding and
   stack the organiser card on the narrowest screens. */
@container vp (max-width: 640px) {
  .wl-section { padding: var(--sp-xl) var(--sp-lg); }
  .wl-org-card { flex-direction: column; text-align: center; padding: var(--sp-xl) var(--sp-lg); }
  .wl-org-card__body { align-items: center; }
  .wl-org-card__badges { justify-content: center; }
  .wl-remove--onlight { top: var(--sp-sm); right: var(--sp-sm); }
}

/* end of 63 */

/* =========================================================================
   §64 Events page — design-agent port (Events.html, 2026-06-21)
   Verbatim copy of design/events.css (handoff bundle 2026-06-21). Powers
   the venues/organisers/admin "My Events" workspace at /members/<u>/my-events/.
   Tokens + chrome + workspace shell from styles.css.
   ========================================================================= */

/* Workspace caps + centres like Wish List, and is a query container so the
   row layout can respond to the REAL content width (stable across the 1023px
   sidenav-collapse). max-width tightened from 920px so the cards don't
   stretch too wide at desktop (Rob 21/06/26). */
.ev-workspace {
  max-width: 720px;
  margin-inline: auto;
  container-type: inline-size;
  container-name: evc;
}

/* ── Verification-pending banner ──────────────────────────────────────────── */
.ev-verify {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  max-width: 720px;
  margin: 0 auto var(--sp-xl);
  padding: var(--sp-md) var(--sp-lg);
  background: var(--color-warning-bg);
  border: 1.5px solid var(--color-warning);
  border-radius: var(--radius-md);
  text-align: center;
}
.ev-verify--inline { margin-top: var(--sp-lg); margin-bottom: var(--sp-xl); }
.ev-verify__text { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.ev-verify__title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 14px;
  color: var(--color-warning);
}
.ev-verify__icon { font-size: 18px; line-height: 1; flex-shrink: 0; }
.ev-verify__title-text { line-height: 1.3; }
.ev-verify__body {
  font-size: 13px;
  color: var(--color-text-secondary);
  line-height: 1.5;
  text-wrap: pretty;
}

/* ── Add-an-Event CTA — dead-centre focal button ──────────────────────────── */
.ev-add-wrap {
  display: flex;
  justify-content: center;
  margin-bottom: var(--sp-xl);
}
.ev-add-btn {
  font-size: 15px;
  padding: 13px 30px 12px;
  border-radius: var(--radius-pill);
}

/* ── Controls row: search + date-range filter ─────────────────────────────── */
.ev-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-lg);
  flex-wrap: nowrap;
  margin-bottom: var(--sp-lg);
}

.ev-search {
  position: relative;
  display: flex;
  align-items: center;
  flex: 0 1 309px;
  min-width: 0;
  max-width: 309px;
}
.ev-search__ph {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  pointer-events: none;
  font: 600 14px var(--font-body);
  color: rgba(3, 27, 131, 0.4);
  transition: opacity var(--duration-fast) var(--ease-out);
}
.ev-search__ph svg { color: var(--color-gold); flex-shrink: 0; }
.ev-search:focus-within .ev-search__ph { opacity: 0; }
/* Scope-bumped to .workspace + !important to defeat Seeko's input[type="text"]
   rule (1px grey border, small radius, 0.5rem 1rem padding, margin-bottom:1rem)
   AND the inline focus rule from functions.php. Mirrors the .ev-pagination__btn
   fix at line 14600. */
.workspace .ev-search__input {
  width: 100% !important;
  text-align: center !important;
  padding: 11px 38px 11px 38px !important;
  margin: 0 !important;
  font: 600 14px var(--font-body) !important;
  color: var(--color-navy) !important;
  background: var(--color-surface) !important;
  border: 2px solid var(--color-gold) !important;
  border-radius: var(--radius-pill) !important;
  outline: none !important;
  box-shadow: none !important;
  transition: box-shadow var(--duration-fast) var(--ease-out) !important;
  min-height: 0 !important;
  max-width: none !important;
}
.workspace .ev-search__input::placeholder { color: rgba(3, 27, 131, 0.65); font-weight: 600; }
html[data-nav="kbd"] .workspace .ev-search__input:focus,
html[data-nav="kbd"] .workspace .ev-search__input:focus-visible {
  border: 2px solid var(--color-gold) !important;
  box-shadow: 0 0 0 2px rgba(204, 153, 0, 0.25) !important;
  outline: none !important;
}
.ev-search__clear {
  position: absolute;
  right: 10px;
  width: 22px;
  height: 22px;
  border: none;
  background: transparent;
  color: var(--color-text-muted);
  display: inline-grid;
  place-items: center;
  border-radius: 50%;
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out);
}
.ev-search__clear:hover { background: var(--color-surface-sunken); color: var(--color-navy); }

/* Date-range filter reuses the existing .section-nav pill switcher verbatim;
   this only keeps it from stretching in the flex controls row. */
.ev-daterange { flex-shrink: 0; }

/* Status tabs (Published / Scheduled / Draft) — replaces the panel heading */
.ev-statustabs { display: inline-flex; }
.ev-statustabs__count {
  margin-left: 7px;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 11px;
  opacity: 0.6;
}
.section-nav__item--active .ev-statustabs__count { opacity: 0.85; }

/* ── List panel ───────────────────────────────────────────────────────────── */
/* overflow-anchor: none — the browser's default scroll-anchoring fights the
   height animation when rows are toggled (auto-adjusts scrollY to keep below-
   viewport content positions constant, producing a jolt-up-then-snap-back
   feel). Disabling here lets our own smoothToPanelTop drive the scroll
   without interference. Rob 21/06/26 — 1024 pagination animation review. */
.ev-panel, .ev-list {
  overflow-anchor: none;
}
.ev-panel {
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: var(--sp-2xl);
  box-shadow: var(--shadow-sm);
}
.ev-panel__head { text-align: center; margin-bottom: var(--sp-xl); }
.ev-panel__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 18px;
  line-height: 1;
  color: var(--color-navy);
  margin: 0;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-sm);
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-pill);
  padding: 7px 12px 7px 18px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12), var(--shadow-sm);
}
.ev-panel__label { display: inline-flex; align-items: center; line-height: 1; }
.ev-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--color-cream);
  color: var(--color-navy);
  border: 1.5px solid var(--color-gold);
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 11px;
  min-width: 22px;
  height: 22px;
  padding: 0 6px 1px;
  border-radius: var(--radius-pill);
  flex-shrink: 0;
  line-height: 1;
}

.ev-list {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: var(--sp-md);
}

/* ── Event row ────────────────────────────────────────────────────────────── */
/* min-height is applied dynamically by JS (event_system_my_events_soft_scroll_script):
   measures every row's natural height, picks the tallest, sets it on every row so
   the list reads as a uniform card stack regardless of free / paid / scheduled / draft
   variants. justify-content:center centres short content vertically. */
.ev-row {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-md);
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: var(--sp-lg);
  box-shadow: 0 2px 8px rgba(26, 26, 46, 0.12);
  text-align: center;
  box-sizing: border-box;
}

/* Date badge → title → meta stacked vertically at every breakpoint
   (Rob 21/06/26 — stack on all widths, not just narrow). */
.ev-row__head {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  row-gap: 18px;
}

/* Date badge */
.ev-row__date {
  width: 56px;
  flex-shrink: 0;
  text-align: center;
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-sm);
  padding: 6px 4px 5px;
  line-height: 1;
  box-shadow: 0 2px 6px rgba(26, 26, 46, 0.16);
}
.ev-row__day {
  display: block;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 20px;
  color: var(--color-navy);
}
.ev-row__month {
  display: block;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-gold);
  margin-top: 2px;
}

/* Main: title + meta */
.ev-row__main { min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.ev-row__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 16px;
  color: var(--color-navy);
  line-height: 1.3;
  text-decoration: none;
}
/* Keep the event title navy on hover — Seeko's a:hover turns links gold, which
   Rob doesn't want, and no underline (D-219). (Rob 29/06/26.) */
.ev-row__title:hover,
.ev-row__title:focus { color: var(--color-navy) !important; text-decoration: none !important; }
.ev-row__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 6px var(--sp-md);
}
.ev-row__meta-item {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 13px;
  color: var(--color-text-secondary);
  line-height: 1.3;
}
.ev-row__meta-item svg { flex-shrink: 0; color: var(--color-gold); }

/* Metric: ticket meter, centred on its own row */
.ev-row__metric {
  display: flex;
  justify-content: center;
  flex-shrink: 0;
}

/* Status pills (mirrors the Attendance chip palette) */
.ev-status {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 4px 12px;
  border-radius: var(--radius-pill);
  border: 1.5px solid transparent;
  white-space: nowrap;
}
.ev-status--published { background: var(--color-success-bg); color: var(--color-success); border-color: var(--color-success); }
.ev-status--draft     { background: var(--color-cream);      color: var(--color-navy);    border-color: var(--color-gold); }
.ev-status--pending   { background: var(--color-warning-bg); color: var(--color-warning); border-color: var(--color-warning); }
.ev-status--scheduled { background: var(--color-warning-bg); color: var(--color-warning); border-color: var(--color-warning); }

/* Ticket-capacity meter */
.ev-tickets {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 156px;
}
.ev-tickets__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
.ev-tickets__nums {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  font-family: var(--font-heading);
  line-height: 1;
}
.ev-tickets__sold { font-size: 18px; font-weight: 700; color: var(--color-success); }
.ev-tickets__cap { font-size: 12px; font-weight: 600; color: var(--color-text-muted); }
.ev-tickets__badge {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 10px;
  letter-spacing: 0.03em;
  color: var(--color-gold);
  background: var(--color-cream);
  border: 1px solid var(--color-gold);
  border-radius: var(--radius-pill);
  padding: 2px 8px 1px;
  line-height: 1.4;
  white-space: nowrap;
}
.ev-tickets__bar {
  position: relative;
  height: 8px;
  border-radius: var(--radius-pill);
  background: #fff;
  border: 1px solid var(--color-gold);
  overflow: hidden;
}
.ev-tickets__fill {
  position: absolute;
  inset: 0 auto 0 0;
  border-radius: inherit;
  background: var(--color-gold-light);
  transition: width var(--duration-base, 300ms) var(--ease-out);
}
.ev-tickets__label {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 5px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--color-gold);
  line-height: 1;
}
.ev-tickets__label svg { width: 12px; height: 12px; color: var(--color-gold); flex-shrink: 0; }

/* Nearly full → amber badge (bar stays gold) */
.ev-tickets--nearly .ev-tickets__badge { color: var(--color-warning); border-color: var(--color-warning); background: var(--color-warning-bg); }

/* Sold out → green badge + label (bar stays gold) */
.ev-tickets--full .ev-tickets__badge { color: var(--color-success); border-color: var(--color-success); background: var(--color-success-bg); }
.ev-tickets--full .ev-tickets__label { color: var(--color-success); }
.ev-tickets--full .ev-tickets__label svg { color: var(--color-success); }

/* Free / uncapped event — count + label, centred in the column, no bar/icon */
.ev-tickets--free {
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 3px;
  width: 156px;
}
.ev-tickets--free .ev-tickets__count {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 18px;
  color: var(--color-success);
  line-height: 1;
}

/* Actions */
.ev-row__actions {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-sm);
  flex-shrink: 0;
}
/* Edit + View row buttons — EXACTLY the same size + style. The selector
   carries `.btn.btn--sm` so it reaches specificity 1,5,0 and beats the
   universal `#buddypress .workspace .btn.btn--primary:not(.att-cancel-btn)`
   padding rule (1,4,0) that was making Edit taller/wider than View (Edit is
   a primary button, View a ghost — so only Edit picked up the bigger primary
   padding). Equal padding + equal min-width makes them identical regardless
   of label text width. (T-S119-018, Rob 29/06/26: "they should be exactly the same".) */
#buddypress .workspace .ev-row .ev-row__edit.btn.btn--sm,
#buddypress .workspace .ev-row .ev-row__view.btn.btn--sm {
  gap: 6px !important;
  padding: 8px 14px !important;
  min-width: 96px !important;
  background: var(--color-surface) !important;
  border: 1.5px solid var(--color-gold) !important;
  color: var(--color-navy) !important;
  box-shadow: var(--shadow-gold-hover) !important;
  transform: none !important;
}
#buddypress .workspace .ev-row .ev-row__edit:hover,
#buddypress .workspace .ev-row .ev-row__view:hover,
html[data-nav="kbd"] #buddypress .workspace .ev-row .ev-row__edit:focus-visible,
html[data-nav="kbd"] #buddypress .workspace .ev-row .ev-row__view:focus-visible {
  background: var(--color-cream) !important;
  border: 1.5px solid var(--color-gold) !important;
  color: var(--color-navy) !important;
  box-shadow: 0 2px 6px rgba(26, 26, 46, 0.14) !important;
  transform: none !important;
}
/* Pressed and in-flight (D-640): darker cream, no shadow while the request is held. R3-08 25/09/26:
   split out of the combined :hover/:active/:focus-visible rule above, which still painted the
   pressed state with the old navy shadow (S231 vintage). Hover/focus-visible keep their own rule
   above; border/text colour for the pressed state still come from the base rule three rules up
   EXCEPT while pressed, see below. First cut of this rule used :active alone (1,4,0 - .workspace
   .ev-row .ev-row__edit :active) and measured live as a no-op: the base rule three rules up chains
   .btn.btn--sm too (1,5,0 - .workspace .ev-row .ev-row__edit .btn .btn--sm) and, both being
   !important, the higher-specificity base rule kept painting rest's white fill and gold shadow
   through a genuine held page.mouse.down() (confirmed matches(':active') true, computed style still
   rest). The same gap silently sat under :hover/:focus-visible above too - out of this item's scope
   (pressed state only) so flagged rather than fixed here. This rule now repeats .btn.btn--sm so its
   specificity (1,6,0) clears the base rule's (1,5,0); background is redeclared for the same reason. */
#buddypress .workspace .ev-row .ev-row__edit.btn.btn--sm:active,
#buddypress .workspace .ev-row .ev-row__view.btn.btn--sm:active {
  background: var(--color-cream-hover) !important;
  box-shadow: none !important;
}

/* Panel-level filtered-empty note */
.ev-panel__empty {
  text-align: center;
  padding: var(--sp-2xl) var(--sp-lg);
  color: var(--color-text-secondary);
  font-size: 14px;
  line-height: 1.6;
}
.ev-panel__empty strong {
  display: block;
  font-family: var(--font-heading);
  color: var(--color-navy);
  font-size: 15px;
  margin-bottom: 2px;
}

/* ── Pagination (mirrors Attendance / Wish List) ──────────────────────────── */
.ev-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-lg);
  margin-top: var(--sp-xl);
}
/* Scope-bumped to .workspace + padding:0 + margin:0 to beat Seeko's
   `button` rule (width:auto, padding:0.5rem 1rem, border:1px transparent,
   margin-bottom:1rem). Mirrors the Wish List fix at §63 (line 14600). */
.workspace .ev-pagination__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  margin: 0;
  border-radius: 50%;
  border: 1.5px solid var(--color-gold);
  background: var(--color-surface);
  color: var(--color-navy);
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-out);
}
.workspace .ev-pagination__btn:hover:not(:disabled) { background: var(--color-cream); transform: scale(1.08); }
.workspace .ev-pagination__btn:disabled { opacity: 0.3; cursor: default; }
.workspace .ev-pagination__btn svg { display: block; }
.ev-pagination__info {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 13px;
  color: var(--color-navy);
}

/* ── Full-page empty state ────────────────────────────────────────────────── */
.ev-empty {
  text-align: center;
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  padding: var(--sp-4xl) var(--sp-2xl);
  max-width: 560px;
  margin: 0 auto;
}
.ev-empty__badge {
  width: 88px;
  height: 88px;
  margin: 0 auto var(--sp-lg);
  display: grid;
  place-items: center;
  background: #fff;
  border: 2px solid var(--color-gold);
  border-radius: 50%;
  box-shadow: var(--shadow-gold-hover); /* R3-24 24/09/26: was a navy/grey shadow on a gold-bordered circle. */
  font-size: 44px;
  line-height: 1;
  text-shadow: 0 2px 3px rgba(3, 27, 131, 0.22);
}
/* S220 14/09/2026, Rob: "On the events page in the dashboard, the ticket icon is not centered."
   It was an EMOJI (&#127903;&#65039;) with a hand-tuned translateY(2px) trying to compensate for
   where the font puts it in its line box, which is exactly why it drifted. It is also the last
   member-facing pictogram emoji I have found, so GLOB-13 was one glyph short of true. The glyph
   is emptied and the brand ticket is painted in its place, centred by the background box, so
   nothing depends on a font's metrics any more and there is no nudge left to drift. */
.ev-empty__badge-ink {
  display: block;
  width: 44px;
  height: 44px;
  font-size: 0;
  line-height: 0;
  text-shadow: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M2.6 7.2h18.8v3.1a1.7 1.7 0 0 0 0 3.4v3.1H2.6v-3.1a1.7 1.7 0 0 0 0-3.4z%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22 stroke-linejoin=%22round%22/%3E%3Cpath d=%22M7.4 10.2h3.4M7.4 13.8h3.4M14.2 10.2h2.6M14.2 13.8h2.6%22 stroke=%22%23031B83%22 stroke-width=%221.5%22 stroke-linecap=%22round%22/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center center;
  background-size: contain;
}
.ev-empty__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 22px;
  color: var(--color-navy);
  margin: 0 0 var(--sp-sm);
  text-wrap: balance;
}
.ev-empty__hint {
  font-size: 15px;
  color: var(--color-text-secondary);
  line-height: 1.6;
  text-wrap: pretty;
  margin: 0 auto var(--sp-xl);
  max-width: 400px;
}
.ev-empty__cta {
  font-size: 15px;
  padding: 13px 30px 12px;
  border-radius: var(--radius-pill);
}

/* ── Form host view ───────────────────────────────────────────────────────── */
.ev-form-view { max-width: 720px; margin: 0 auto; }
.ev-back {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 13px;
  color: var(--color-navy);
  background: transparent;
  border: none;
  padding: 6px 4px;
  cursor: pointer;
  margin-bottom: var(--sp-lg);
  text-decoration: none;
  transition: gap var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out);
}
.ev-back svg { color: var(--color-gold); }
.ev-back:hover { gap: 11px; color: var(--color-navy-light); }
.ev-form-head { text-align: center; margin-bottom: var(--sp-xl); }
.ev-form-head__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 28px;
  color: var(--color-navy);
  margin: 0;
}
.ev-form-head__sub {
  font-size: 15px;
  color: var(--color-text-secondary);
  margin: var(--sp-xs) 0 0;
}
.ev-form-slot {
  border: 2px dashed var(--color-border-strong);
  border-radius: var(--radius-md);
  background:
    repeating-linear-gradient(45deg, rgba(3,27,131,0.025) 0 10px, transparent 10px 20px);
  padding: var(--sp-4xl) var(--sp-2xl);
  text-align: center;
}
.ev-form-slot__tag {
  display: inline-block;
  font-family: 'Courier New', monospace;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  background: var(--color-surface);
  border: 1.5px solid var(--color-border-strong);
  border-radius: var(--radius-pill);
  padding: 6px 16px;
  margin-bottom: var(--sp-lg);
}
.ev-form-slot__note {
  font-size: 14px;
  color: var(--color-text-secondary);
  line-height: 1.6;
  max-width: 440px;
  margin: 0 auto;
  text-wrap: pretty;
}

/* ── Responsive ───────────────────────────────────────────────────────────── */
/* Tablet/narrow: collapse the row to a stacked card. The date badge moves
   inline with the title; status/tickets and actions sit on their own rows. */
@container evc (max-width: 720px) {
  .ev-controls { flex-direction: column; align-items: center; }
  .ev-search { flex: 0 0 auto; width: 100%; max-width: 360px; }
  .ev-daterange { align-self: center; }
}
@container evc (max-width: 560px) {
  .ev-row { gap: var(--sp-md); }
  .ev-row__edit, .ev-row__view { flex: 1; justify-content: center; }
}
/* Narrowest (≤400px): shrink the panel's horizontal padding so the inside
   gap (panel-edge → card-edge) matches the outside gap (screen-edge →
   panel-edge ≈ 17px at 360px). Measured live before setting (Rob 21/06/26
   — "make it symmetrical"). var(--sp-lg) = 16px + 1.5px border = ~17.5px. */
@container evc (max-width: 400px) {
  .ev-panel {
    padding-left: var(--sp-lg);
    padding-right: var(--sp-lg);
  }
  /* Tighten the top/bottom padding at the narrowest viewports so the date
     doesn't sit in a big empty band (Rob 21/06/26). */
  .ev-row {
    padding-top: var(--sp-sm);
    padding-bottom: var(--sp-sm);
  }
}
/* end of 64 */

/* =========================================================================
   §65 Suggestions page — design-agent port (Suggestions.html, 2026-06-21)
   Verbatim copy of design/suggestions.css (handoff bundle 2026-06-21).
   Powers /members/<u>/suggestions/. overflow-anchor: none on the list +
   track per the §10 standing rule (Rob 21/06/26).
   ========================================================================= */

.sg-wrap {
  max-width: 660px;
  margin-inline: auto;
  width: 100%;
}

.sg-pill {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-sm);
  margin: calc(-1 * var(--sp-md)) auto var(--sp-2xl);
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-success);
  background: var(--color-success-bg);
  border: 1.5px solid var(--color-success);
  border-radius: var(--radius-pill);
  padding: 7px 18px 6px;
  width: fit-content;
  line-height: 1;
  box-shadow: 0 2px 8px rgba(39, 166, 68, 0.12);
}
.sg-pill__dot { width: 5px; height: 5px; border-radius: 50%; background: currentColor; flex-shrink: 0; transform: translateY(-1px); }

/* ── Submission form card ────────────────────────────────────────────────── */
.sg-form {
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  padding: var(--sp-2xl);
}
.sg-field { display: flex; flex-direction: column; align-items: center; gap: var(--sp-sm); }
.sg-field + .sg-field { margin-top: var(--sp-xl); }
.sg-label {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-navy);
}
.sg-label__opt {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 12px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--color-text-muted);
  margin-left: 6px;
}

.sg-chips { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--sp-sm); }
.workspace .sg-chip {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  font-family: var(--font-heading) !important;
  font-weight: 700 !important;
  font-size: 13px !important;
  color: var(--color-navy) !important;
  background: var(--color-cream) !important;
  border: 1.5px solid var(--color-gold) !important;
  border-radius: var(--radius-pill) !important;
  padding: 7px 15px !important;
  margin: 0 !important;
  line-height: 1 !important;
  cursor: pointer !important;
  /* D-640/D-651 (S235 SHADOWS-5, 25/09/26): was a navy shadow, must be gold. */
  box-shadow: var(--shadow-gold-hover) !important;
  transform: translateY(-1px) !important;
  transition: background var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out) !important;
}
.workspace .sg-chip--active {
  background: var(--color-cream-hover) !important;
  color: var(--color-navy) !important;
  border-color: var(--color-gold) !important;
  transform: translateY(-1px) !important;
  /* D-651: pressed and selected states carry no shadow - this was still the navy rest shadow. */
  box-shadow: none !important;
}
.workspace .sg-chip:active { transform: translateY(0) !important; box-shadow: none !important; }
.sg-ink { display: inline-block; line-height: 1; will-change: transform; }

/* Inputs — scope-bumped to defeat Seeko input rules */
.workspace .sg-input,
.workspace .sg-textarea {
  width: 100% !important;
  padding: 12px 14px !important;
  margin: 0 !important;
  font: 400 15px var(--font-body) !important;
  color: var(--color-navy) !important;
  background: var(--color-surface) !important;
  border: 2px solid var(--color-gold) !important;
  border-radius: var(--radius-md) !important;
  outline: none !important;
  box-shadow: none !important;
  transition: box-shadow var(--duration-fast) var(--ease-out) !important;
}
.workspace .sg-input { text-align: center !important; }
.workspace .sg-input::placeholder { text-align: center; }
.workspace .sg-input::placeholder,
.workspace .sg-textarea::placeholder { color: rgba(3, 27, 131, 0.65); font-style: italic; }
html[data-nav="kbd"] .workspace .sg-input:focus,
html[data-nav="kbd"] .workspace .sg-textarea:focus,
html[data-nav="kbd"] .workspace .sg-input:focus-visible,
html[data-nav="kbd"] .workspace .sg-textarea:focus-visible {
  border: 2px solid var(--color-gold) !important;
  box-shadow: 0 0 0 2px rgba(204, 153, 0, 0.25) !important;
  outline: none !important;
}
.workspace .sg-textarea { text-align: center !important; min-height: 132px !important; resize: vertical !important; line-height: 1.55 !important; }
.workspace .sg-textarea::placeholder { text-align: center; }
.sg-count {
  align-self: flex-end;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}
.sg-count--over { color: var(--color-error); }

.sg-drop {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 92px;
  padding: var(--sp-lg);
  border: 2px dashed var(--color-gold);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-secondary);
  font-family: var(--font-body);
  font-size: 14px;
  text-align: center;
  cursor: pointer;
  transition: border-color var(--duration-fast) var(--ease-out),
              background var(--duration-fast) var(--ease-out);
}
.sg-drop--drag { border-color: var(--color-gold); background: var(--color-cream); }
.sg-drop__glyph { font-size: 22px; line-height: 1; filter: drop-shadow(0 2px 4px rgba(3, 27, 131, 0.28)); }
.sg-drop__text { color: var(--color-gold-dark); font-weight: 700; font-family: var(--font-heading); }
.sg-drop__hint { font-size: 12px; color: var(--color-text-muted); }
.sg-drop kbd {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 11px;
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  padding: 1px 5px;
  color: var(--color-navy);
}

.sg-shot {
  width: 100%;
  display: flex;
  align-items: center;
  gap: var(--sp-md);
  padding: var(--sp-sm) var(--sp-md);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  background: var(--color-cream);
}
.sg-shot__thumb {
  width: 46px; height: 46px;
  border-radius: var(--radius-sm);
  object-fit: cover;
  border: 1px solid var(--color-gold);
  background: var(--color-surface-sunken);
  flex-shrink: 0;
}
.sg-shot__name {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 13px;
  color: var(--color-navy);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
  text-align: left;
}
.workspace .sg-shot__remove {
  flex-shrink: 0;
  width: 28px !important;
  height: 28px !important;
  padding: 0 !important;
  margin: 0 !important;
  border-radius: 50% !important;
  border: 1.5px solid var(--color-error) !important;
  background: transparent !important;
  color: var(--color-error) !important;
  display: inline-grid !important;
  place-items: center !important;
  cursor: pointer !important;
  transition: background var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out) !important;
}
.workspace .sg-shot__remove:hover { background: var(--color-error) !important; color: #fff !important; }
.workspace .sg-shot__remove svg { display: block; }

.sg-submit {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-md);
  margin-top: var(--sp-2xl);
}
.workspace .sg-submit .btn { min-width: 240px !important; }
/* Send button — white fill, gold border, raised shadow; presses to light cream.
   Scoped + !important to beat the theme's submit-button styling. */
#buddypress .workspace .sg-submit .btn.btn--primary {
  background: var(--color-surface) !important;
  border: 2px solid var(--color-gold) !important;
  color: var(--color-navy) !important;
  box-shadow: var(--shadow-gold-hover) !important;
}
#buddypress .workspace .sg-submit .btn.btn--primary:hover {
  background: var(--color-surface) !important;
  transform: translateY(-2px) !important;
  box-shadow: var(--shadow-gold-hover) !important;
}
#buddypress .workspace .sg-submit .btn.btn--primary:active {
  background: var(--color-cream) !important;
  transform: translateY(0) !important;
  box-shadow: none !important;
}
/* S222: the suggestions Send button while the suggestion is posting. COMPUTED before:
   rgb(142,152,199) on white, 2.80 to 1. Same treatment as the rest, per 46.Z. */
#buddypress .workspace .sg-submit .btn.btn--primary:disabled,
#buddypress .workspace .sg-submit .btn.btn--disabled {
  opacity: 1 !important;
  cursor: not-allowed !important;
  transform: none !important;
  box-shadow: none !important;
}
.sg-sent {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 13px;
  color: var(--color-success);
  background: var(--color-success-bg);
  border-radius: var(--radius-pill);
  padding: 6px 16px;
  animation: sg-pop var(--duration-normal) var(--ease-out);
}
@keyframes sg-pop { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

/* ── Tracked-list section ────────────────────────────────────────────────── */
/* overflow-anchor: none — standing rule §10 (Rob 21/06/26). */
.sg-track, .sg-list { overflow-anchor: none; }
.sg-track { margin-top: var(--sp-3xl); }
.sg-track__head {
  text-align: center;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 22px;
  color: var(--color-navy);
  margin: 0 0 var(--sp-lg);
}

.sg-notice {
  max-width: 520px;
  margin: 0 auto var(--sp-xl);
  text-align: center;
  font-size: 14px;
  line-height: 1.55;
  color: var(--color-navy);
  background: var(--color-cream);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: var(--sp-md) var(--sp-xl);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
  text-wrap: pretty;
}
.sg-notice strong { font-weight: 700; color: var(--color-navy); }

.sg-list { display: flex; flex-direction: column; gap: var(--sp-lg); }
.sg-card {
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  padding: var(--sp-xl);
  text-align: center;
  transition: transform var(--duration-fast) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out);
  animation: sg-pop var(--duration-normal) var(--ease-out);
}
.sg-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-gold-hover); }
.sg-card__top {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-md);
  margin-bottom: var(--sp-lg);
}
.sg-card__cat {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-gold-dark);
}
.sg-card__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 18px;
  color: var(--color-navy);
  margin: 0 0 var(--sp-md);
  line-height: 1.25;
  text-wrap: pretty;
}
.sg-card__body {
  font-size: 15px;
  color: var(--color-text-secondary);
  line-height: 1.55;
  margin: 0;
  text-wrap: pretty;
}

.sg-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  padding: 4px 11px 5px;
  border-radius: var(--radius-pill);
  border: 1.5px solid currentColor;
  line-height: 1;
}
.sg-status::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; transform: translateY(-1px); }
.sg-status--unread   { color: var(--color-warning);   background: var(--color-warning-bg); }
.sg-status--seen     { color: var(--color-success);   background: var(--color-success-bg); }

.sg-card__foot {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-md);
  margin-top: var(--sp-md);
  padding-top: var(--sp-md);
  border-top: 1px solid var(--color-gold);
}
.sg-card__time {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 12px;
  color: var(--color-gold-dark);
}
.sg-card__chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 11px;
  color: var(--color-success);
  background: var(--color-success-bg);
  border: 1px solid currentColor;
  border-radius: var(--radius-pill);
  padding: 3px 10px 4px;
}

.sg-empty {
  text-align: center;
  background: var(--color-surface);
  border: 1.5px dashed var(--color-gold);
  border-radius: var(--radius-md);
  padding: var(--sp-3xl) var(--sp-2xl);
}
/* S222 14/09/26, ICON1, Rob item 8: "keep the bulb but make it an SVG". The slot was sized for a
   44px emoji and line-height: 1 gave it a text line box; an inline SVG sits on the baseline, which
   measured 48.00px and pushed the title down 4.00px. line-height: 0 makes the slot the glyph's own
   height: measured 44.00px, title shift versus the emoji 0.00px. */
.sg-empty__glyph { font-size: 44px; line-height: 0; margin-bottom: var(--sp-md); }
.sg-empty__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 18px;
  color: var(--color-navy);
  margin: 0 0 var(--sp-xs);
}
.sg-empty__hint {
  font-size: 14px;
  color: var(--color-text-secondary);
  line-height: 1.6;
  max-width: 380px;
  margin: 0 auto;
  text-wrap: pretty;
}

/* ── Pagination — scope-bumped per the §63 wishlist fix. */
.sg-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-lg);
  margin-top: var(--sp-xl);
}
.workspace .sg-pagination__btn {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  width: 36px !important;
  height: 36px !important;
  padding: 0 !important;
  margin: 0 !important;
  border-radius: 50% !important;
  border: 1.5px solid var(--color-gold) !important;
  background: var(--color-surface) !important;
  color: var(--color-navy) !important;
  cursor: pointer !important;
  transition: background var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out) !important;
}
.workspace .sg-pagination__btn:hover:not(:disabled) { background: var(--color-cream) !important; transform: scale(1.08) !important; }
.workspace .sg-pagination__btn:disabled { opacity: 0.3 !important; cursor: default !important; }
.workspace .sg-pagination__btn svg { display: block; }
.sg-pagination__info {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 13px;
  color: var(--color-navy);
}

/* Responsive (mirror design's @container vp max-width: 640px) */
@media (max-width: 640px) {
  .sg-form { padding: var(--sp-xl) var(--sp-lg); }
  .sg-card { padding: var(--sp-lg); }
  .sg-card__top { flex-wrap: wrap; gap: var(--sp-sm); }
}
/* end of 65 */

/* =========================================================================
   §66 Settings page — design-agent port (Settings.html, 2026-06-24)
   Verbatim copy of design_handoff_settings/design/settings.css.
   ========================================================================= */

/* §66.0 Container-query mount.
   Spec uses @container vp (max-width: 640px). Mount on .bp-user.settings
   #item-body, NOT .app (the skill calls this out: .app is capped to ~978px
   by BuddyPress wrappers so vp queries fire permanently). */
.bp-user.settings #item-body { container-type: inline-size; container-name: vp; }

.st-wrap {
  max-width: 660px;
  margin-inline: auto;
  width: 100%;
}

/* §66.1 Card */
.st-card {
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  padding: var(--sp-2xl);
  text-align: center;
}
.st-card + .st-card { margin-top: var(--sp-xl); }
.st-card__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 22px;
  color: var(--color-navy);
  margin: 0 0 var(--sp-xl);
}

/* §66.2 Fields */
.st-field { display: flex; flex-direction: column; align-items: center; gap: var(--sp-sm); }
.st-field + .st-field { margin-top: var(--sp-xl); }
.st-label {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-navy);
  text-align: center;
}
.st-label__opt {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 12px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--color-text-muted);
  margin-left: 6px;
}
/* Scope-bumped to .workspace to defeat Seeko's
   `input[type="password"], input[type="email"], ... { font-size:1rem; padding:0.5rem 1rem; border-width:1px }`
   at (0,1,1). .workspace .st-input = (0,2,0) wins. Same fix for ::placeholder
   vs `input[type="password"]::-webkit-input-placeholder { color:#9A9A9A }`. */
.workspace .st-input,
.workspace .st-select {
  width: 100%;
  /* Cap form controls so short fields don't span the full 660px card -
     they centre within the field (label is already centred). */
  max-width: 420px;
  padding: 12px 14px;
  font: 400 15px var(--font-body);
  color: var(--color-navy);
  background: var(--color-surface);
  border: 2px solid var(--color-gold);
  border-radius: var(--radius-md);
  outline: none;
  text-align: center;
  text-align-last: center;
  transition: box-shadow var(--duration-fast) var(--ease-out);
}
.workspace .st-input::placeholder { text-align: center; color: rgba(3, 27, 131, 0.65); font-style: italic; }
html[data-nav="kbd"] .workspace .st-input:focus,
html[data-nav="kbd"] .workspace .st-select:focus { box-shadow: 0 0 0 2px rgba(204, 153, 0, 0.25); }
.workspace .st-select { cursor: pointer; appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23CC9900' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 14px center; padding-right: 38px;
}

/* §66.3 Helper note under a field/group */
.st-note {
  font-size: 13px;
  color: var(--color-text-secondary);
  line-height: 1.55;
  max-width: 440px;
  margin: 2px auto 0;
  text-wrap: pretty;
}

/* §66.4 Username field with @ prefix */
.st-username {
  display: flex;
  align-items: stretch;
  width: 100%;
  max-width: 420px;
  border: 2px solid var(--color-gold);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-surface);
  transition: box-shadow var(--duration-fast) var(--ease-out);
}
html[data-nav="kbd"] .st-username:focus-within { box-shadow: 0 0 0 2px rgba(204, 153, 0, 0.25); }
.st-username__at {
  /* S222 14/09/26 (CHK1, item 14). ROB: "it's not centred properly, use your overlays and
     measure the ink as always." Measured from the painted ink at deviceScaleFactor 8, the 

     sat 0.94px BELOW the centre of its cream cell at 360 and 1280, and 1.94px below at 768
     and 600. Horizontally it was already inside the browser's own sub-pixel noise (0.5px
     right at 360, 0.25px left at every wider width), so nothing is done to it: nudging it
     left made the wider widths worse. place-items:center centres the LINE BOX, and the 

     glyph's ink sits low inside its own line, which is the whole of the error. 3px of
     bottom padding lifts the centred line by 1.5px and lands the ink 0.06px from the cell
     centre at 360, 600, 768 and 1280 alike. The cell is 46px wide with its height set by
     the flex stretch, so the padding moves the glyph and nothing else. */
  padding-bottom: 3px;
  display: grid;
  place-items: center;
  width: 46px;
  flex-shrink: 0;
  background: var(--color-cream);
  border-right: 2px solid var(--color-gold);
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 18px;
  color: var(--color-gold-dark);
}
/* Scope-bumped — same reason as .workspace .st-input above.
   margin-bottom: 0 defeats Seeko's `input { margin-bottom: 1rem }` which under
   flex `align-items: stretch` stretches the @ box 18px past the visible input
   bottom, producing a phantom vertical line. Rob 25/06/26. */
.workspace .st-username input {
  flex: 1;
  min-width: 0;
  border: 0;
  outline: none;
  margin: 0;
  /* Balance the 46px "@" prefix box on the left so centred text sits in the
     true centre of the whole field, not just the input portion. */
  padding: 12px 60px 12px 14px;
  font: 400 15px var(--font-body);
  color: var(--color-navy);
  text-align: center;
  background: transparent;
}
/* S206 04/09/2026 - matched to the relationship dropdown (.st-dd__value--ph), which is navy at
   55% with font-weight 600. The WEIGHT is what makes it read blue rather than grey; opacity
   alone never fixed it. Changed here, at the one rule that owns this placeholder, rather than
   adding a more specific one on top - Rob: "There should only ever be one rule. There
   shouldn't be layers of rules." */
.workspace .st-username input::placeholder { color: rgba(3, 27, 131, 0.65); font-style: italic; font-weight: 600; }

/* §66.5 Date-of-birth row */
.st-dob { display: flex; gap: var(--sp-md); width: 100%; max-width: 420px; margin-inline: auto; justify-content: center; }
.st-dob .st-select { flex: 1; min-width: 0; }
.st-dob .st-dd { flex: 1; min-width: 0; }

/* §66.6 On-brand custom dropdown */
.st-dd { position: relative; width: 100%; max-width: 420px; }
/* Canonical custom-dropdown pattern - see RULES/canonical-dropdown.md.
   Trigger: cream bg + gold border, flips to gold bg + navy border when open. */
.st-dd__btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  min-height: 40px;
  padding: 8px 32px;
  font: 600 14px var(--font-body);
  color: var(--color-navy);
  background: var(--color-surface);
  border: 2px solid var(--color-gold);
  border-radius: 10px;
  cursor: pointer;
  text-align: center;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
  transition: background var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out);
}
.st-dd--open .st-dd__btn {
  background: var(--color-surface);
  border-color: var(--color-gold);
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.18);
}
/* Hover neutraliser — Seeko's `button:hover { background:#f0f0f0; color:#191919;
   border-color:transparent }` (§18) wins at (0,1,1) over the bare .st-dd__btn rule.
   Defeat all three properties explicitly and keep the resting (closed) styling on
   hover. When the menu is open, restate the gold border too so hover cannot switch
   it blue. Rob 25/06/26: no hover change on these. */
.workspace .st-dd__btn:hover {
  background: var(--color-surface) !important;
  color: var(--color-navy) !important;
  border-color: var(--color-gold) !important;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12) !important;
}
.workspace .st-dd--open .st-dd__btn:hover {
  border-color: var(--color-gold) !important;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.18) !important;
}
.st-dd__value { display: inline-block; line-height: 1; will-change: transform; }
.st-dd__value--ph { color: rgba(3, 27, 131, 0.65); font-style: italic; }
.st-dd--open .st-dd__value--ph { color: var(--color-navy); }
.st-dd__chev { position: absolute; right: 14px; top: 50%; width: 14px; height: 14px; transform: translateY(-50%); color: var(--color-navy); transition: transform var(--duration-fast) var(--ease-out); }
.st-dd--open .st-dd__chev { transform: translateY(-50%) rotate(180deg); }
.st-dd__menu {
  position: absolute;
  z-index: 98;      /* S245 row 35: 98, was 1000 (header is 99; see 26.5.7) */
  top: calc(100% + 10px);
  left: 0; right: 0;
  max-height: 280px;
  overflow-y: auto;
  margin: 0;
  padding: 14px;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--color-surface);
  border: 2px solid var(--color-gold);
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
  scrollbar-width: thin;
  scrollbar-color: var(--color-gold) transparent;
  animation: st-dd-in 180ms var(--ease-out);
}
@keyframes st-dd-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.st-dd__menu::-webkit-scrollbar { width: 8px; }
.st-dd__menu::-webkit-scrollbar-thumb { background: var(--color-gold); border-radius: var(--radius-pill); }
.st-dd__opt {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 10px 14px;
  border: 1.5px solid rgba(3, 27, 131, 0.2);
  border-radius: 8px;
  background: var(--color-surface);
  font: 600 13px var(--font-body);
  color: var(--color-navy);
  text-align: center;
  white-space: nowrap;
  cursor: pointer;
  transition: background 150ms var(--ease-out), border-color 150ms var(--ease-out);
}
/* Canonical option states: hover AND selected share cream + gold border;
   the selected option is differentiated ONLY by bold weight. */
.st-dd__opt:hover { background: var(--color-cream); border-color: var(--color-gold); }
.st-dd__opt--active { background: var(--color-cream); border-color: var(--color-gold); font-weight: 700; }

/* §66.7 Action button — uses the canonical .btn-dashboard pattern (§43.2) site-wide
   cream → cream-hover + translateY(-1px), not the design's white→white shadow variant.
   Rob 25/06/26: site-wide canonical wins per skill rule 11. */
.st-actions { display: flex; flex-direction: column; align-items: center; gap: var(--sp-md); margin-top: var(--sp-2xl); }
.st-actions .btn-dashboard { min-width: 240px; }
@keyframes st-pop { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

/* §66.8 Rule heading (centred label with gold lines either side) */
.st-rule {
  display: flex;
  align-items: center;
  gap: var(--sp-lg);
  margin: var(--sp-2xl) 0 var(--sp-lg);
}
.st-rule::before, .st-rule::after { content: ""; flex: 1; height: 1px; background: var(--color-gold); opacity: 0.6; }
.st-rule span {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-navy);
}

/* §66.9 Safeguard note (Family Links intro) */
.st-safeguard {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-sm);
  background: var(--color-cream);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: var(--sp-xl);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.10);
}
.st-safeguard__glyph { display: inline-flex; width: 26px; height: 26px; font-size: 0; line-height: 0; flex-shrink: 0; filter: drop-shadow(0 2px 4px rgba(3, 27, 131, 0.22)); }
.st-safeguard__text {
  margin: 0;
  font-size: 13.5px;
  color: var(--color-navy);
  line-height: 1.6;
  text-wrap: pretty;
}
.st-safeguard__text strong { font-weight: 700; }

/* §66.10 Hint callout (dashed) */
.st-hint {
  font-size: 13px;
  color: var(--color-text-secondary);
  line-height: 1.55;
  background: var(--color-cream);
  border: 1.5px dashed var(--color-gold);
  border-radius: var(--radius-md);
  padding: var(--sp-md) var(--sp-lg);
  max-width: 460px;
  margin: 0 auto var(--sp-lg);
  text-wrap: pretty;
}

/* §66.11 Link cards (pending / active) */
.st-links { display: flex; flex-direction: column; gap: var(--sp-md); }
.st-link {
  display: flex;
  align-items: center;
  gap: var(--sp-lg);
  text-align: left;
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: var(--sp-md) var(--sp-lg);
  box-shadow: var(--shadow-sm);
  animation: st-pop var(--duration-normal) var(--ease-out);
}
.st-link__sigil {
  width: 46px; height: 46px;
  flex-shrink: 0;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 16px;
  color: var(--color-gold);
  background: linear-gradient(135deg, #2a3556, #1f2848);
  border: 2.5px solid var(--color-gold);
}
.st-link__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.st-link__name {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 15px;
  color: var(--color-navy);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.st-link__meta { display: flex; align-items: center; gap: var(--sp-sm); flex-wrap: wrap; }
.st-link__rel {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-navy);
  background: rgba(204, 153, 0, 0.12);
  border: 1px solid rgba(204, 153, 0, 0.5);
  border-radius: var(--radius-pill);
  /* Inner text is a [data-ink] span centred at runtime by stAlignInk, so
     vertical padding is symmetric - no hand-tuned nudge to drift out of sync. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 4px 9px;
}
.st-link__when { font-size: 12px; color: var(--color-text-muted); font-weight: 600; }
.st-link__actions { display: flex; gap: var(--sp-sm); flex-shrink: 0; }

/* §66.12 Status pill */
.st-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  padding: 4px 11px 5px;
  border-radius: var(--radius-pill);
  border: 1.5px solid currentColor;
  line-height: 1;
}
.st-status__dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex-shrink: 0; }
.st-status--wait  { color: var(--color-warning); background: var(--color-warning-bg); }
.st-status--in    { color: var(--color-info);    background: rgba(37, 99, 235, 0.09); }
.st-status--active{ color: var(--color-success); background: var(--color-success-bg); }

/* §66.13 Small inline buttons on link cards.
   Rob 25/06/26: padding made symmetric (was 7/6 top/bottom in spec). The
   design's +1px top bias was meant for offline rendering but combines with
   stAlignInk's lift to push "Cancel"/"Accept"/"Decline"/"Revoke" caps visibly
   above the pill centre. Symmetric padding lets stAlignInk land the ink centre
   exactly at the box centre, matching Rule §9. */
/* S245 row 129 (D-512, "a card button is the site's button, not a fourth family"; D-508, every button takes 10px corners; row 130, the one canonical pop). THE LIVE MARKUP of this
   row is buddypress/legacy/members/single/settings/general.php (Cancel under Sent, Accept and Decline under Received, Revoke under Active links); the .uks-family-* list at 38.2 above is
   the RETIRED page (family-link.php 5.1) and is not rendered. MEASURED live with that exact markup placed in the page in the browser (no test account holds a link), a real pointer on
   each of the four: rest white, a 1.5px ring in red (Cancel, Decline, Revoke) or green (Accept), a 9999px pill, NO shadow; hovered a SOLID red or green fill with white text and the ring
   gone (Seeko's `button:hover` clears border-color), no lift, no shadow (S227 item 122, Rob: "Nothing should be just solid colour like that"); held down Seeko's grey, rgb(238,238,238)
   with a #191919 label and no ring. They now take the site's button, value for value from the two families the site already has and Rob has passed:
     - Accept, the standard button (.btn--primary, 42.8; Rob's own S207 item A4 ruling for this very button in its retired list: "light cream in with a gold border and navy text; darker cream
       on hover and select"): --color-cream, the gold ring, the navy label; --color-cream-hover hovered and held.
     - Cancel, Decline and Revoke, the red variant (.btn--danger, 42.8): the 6 percent error wash, the --color-error ring and label; the 12 percent wash hovered and held.
     - both: 10px corners (D-508), the ONE shadow --shadow-gold-hover at rest and hovered (the dashboard buttons Rob signed off carry it unchanged on hover) and none when held, the 1px lift on
       a real pointer only and not while held (as .btn--primary and .btn--danger, 42.8), 120ms. The size, the type and the padding are as they were, so stAlignInk's centring of the label
       is untouched.
   The selectors are written through .st-link__actions so that they count 0,2,0 or more: Seeko's `button:focus` (0,1,1) clears box-shadow and would have taken the shadow off the button the
   moment it was clicked, and its `button:not([disabled]):not(.disabled):active` (0,3,1) paints the grey, so the held rules below count 0,5,0. */
.st-link__actions .st-mini {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 12px;
  line-height: 1;
  padding: 7px 13px;
  border-radius: 10px;
  border: 1.5px solid var(--color-gold);
  background: var(--color-cream);
  color: var(--color-navy);
  box-shadow: var(--shadow-gold-hover);
  cursor: pointer;
  transition: background-color 120ms ease-out, color 120ms ease-out, border-color 120ms ease-out, box-shadow 120ms ease-out, transform 120ms ease-out;
}
.st-link__actions .st-mini:hover {
  background: var(--color-cream-hover);
  color: var(--color-navy);
  border-color: var(--color-gold);
}
.st-link__actions .st-mini--danger {
  /* S246 item 129 (ROBS_FIXES row 129), 13/10/26: the rest fill is WHITE, replacing the 6 percent error wash the S245 row 129 block above names. Value read off the Delete for good dialog's
     danger variant, mu-plugins/uksocials-dialog.php line 48 (.uks-dialog-btn--danger, background #FFFFFF; red ring and red label as here). Hover, held, ring, label, shadow, corners, lift and the
     size are already that variant's and are untouched. */
  background: #FFFFFF;
  border-color: var(--color-error);
  color: var(--color-error);
}
.st-link__actions .st-mini--danger:hover {
  background: rgba(196, 28, 28, 0.12);
  border-color: var(--color-error);
  color: var(--color-error);
}
@media (hover: hover) {
.st-link__actions .st-mini:hover:not(:active):not(:disabled) { transform: translateY(-1px); }
}
.st-link__actions .st-mini:not([disabled]):not(.disabled):active {
  background: var(--color-cream-hover);
  border-color: var(--color-gold);
  color: var(--color-navy);
  box-shadow: none;
  transform: none;
}
.st-link__actions .st-mini--danger:not([disabled]):not(.disabled):active {
  background: rgba(196, 28, 28, 0.12);
  border-color: var(--color-error);
  color: var(--color-error);
}
/* F32c (S238, 27/09/2026): the disabled state. On an admin's view of a member's Family & Friends page
   the four row buttons are disabled (inert), as Get a code, Look them up and the request form are.
   MEASURED LIVE before this block: the parent theme's own disabled rule painted them grey
   rgb(248,248,248) with the border gone, and the hover fills above still turned them solid green or
   red under the pointer, so they looked live. The treatment is the site's verified one (46.Z, R3-11,
   D-640: "was the grey/transparent mistake"): each keeps its own border and text colour on the
   darker cream, no shadow, a not-allowed cursor, and it does not change under the pointer. */
.st-mini:disabled,
.st-mini:disabled:hover {
  background: var(--color-cream-hover) !important;
  opacity: 1 !important;
  cursor: not-allowed !important;
  box-shadow: none !important;
  transform: none !important;
}
/* S245 row 129: Accept is the standard cream button now (above), so its disabled ring and label are the gold and navy it keeps (they were the green it no longer has). */
.st-mini--accept:disabled,
.st-mini--accept:disabled:hover { border-color: var(--color-gold) !important; color: var(--color-navy) !important; }
.st-mini--danger:disabled,
.st-mini--danger:disabled:hover { border-color: var(--color-error) !important; color: var(--color-error) !important; }

/* §66.14 Ink-centred label spans (cap-band centroid, DESIGN_RULES §9) */
.st-ink { display: inline-block; line-height: 1; will-change: transform; }

/* §66.15 Empty state */
.st-empty {
  text-align: center;
  background: var(--color-cream);
  border: 1.5px dashed var(--color-gold);
  border-radius: var(--radius-md);
  padding: var(--sp-xl) var(--sp-lg);
  font-size: 14px;
  color: var(--color-text-secondary);
}

/* §66.16 Responsive - design uses @container vp; live mounts container on
   .bp-user.settings #item-body. */
@container vp (max-width: 640px) {
  .st-card { padding: var(--sp-xl) var(--sp-lg); }
  .st-dob { flex-direction: column; }
  /* Stacked card: uniform vertical rhythm between sigil, name, label, when,
     and actions. Name is pulled slightly closer to the sigil above it than to
     the label below it (negative margin trims only the sigil->name gap). */
  .st-link { flex-direction: column; align-items: center; text-align: center; gap: var(--sp-md); }
  .st-link__body { align-items: center; text-align: center; gap: var(--sp-md); margin-top: -4px; }
  .st-link__meta { justify-content: center; }
  .st-link__actions { width: 100%; justify-content: center; }
}
/* end of §66 */

/* =========================================================================
   §67 Event Invites — verbatim port of eventinvites.css
   Menu  = canonical .section-nav gold pills (styles.css).
   Cards = shared .att-res-card shell (§43.1).
   This section only adds the invite-specific: .ei-inviter header, gold venue
   line, quoted .ei-message, .ei-modal detail view, red Declined chip, plus
   the small count bubble appended to each menu pill.
   ========================================================================= */

/* §67.1 Menu pill count (plain inline number, matches the Account menu style) */
.ei-menu-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
/* Circular count bubble - cream fill, gold border, navy number (matches the
   sidenav notification badge per README). Not gold-filled. */
.ei-menu-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  /* S245 row 141 (Rob, the 9th of October 2026: "the number badges and numbers within the badges on the folders in the top nav are not centered.
     They all need bumping up a little bit."). The three declarations below are .mi-menu-count's, value for value (section 68.2.1, S220,
     14/09/2026, the My Interests tab bubble fixed at Rob's request on the same gold tab pills and not raised again): padding 1px top and 0 bottom, and a lift of 1.391px.
     MEASURED on the live Invites page by the painted ink at 8 times scale, at 1920, 1280, 1024, 768 and 360: the ring sat 0.69px BELOW the
     middle of the capital letters of Pending, Accepted and Declined, and the digit 0.75px below it; the digit sat 0.06px to 0.13px low of its
     own ring. After: the ring 0.31px above and the digit 0.19px to 0.25px above that capital band (the best a ring on whole pixels can do: that capital
     band's middle falls 0.31px off any whole pixel), the digit still 0.06px to 0.13px low of its ring, identical to the My Interests tabs. */
  padding: 1px 5px 0;
  position: relative;
  top: -1.391px;
  border-radius: 50%;
  background: var(--color-cream);
  border: 1.5px solid var(--color-gold);
  color: var(--color-navy);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
}

/* §67.2 Inviter header (centred: Sigil, then clickable name, then meta) */
.ei-inviter {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 4px;
  padding-bottom: var(--sp-lg);
  border-bottom: 1px solid rgba(204, 153, 0, 0.35);
}
.ei-inviter__sigil-link {
  display: inline-flex;
  margin-bottom: var(--sp-xs);
  border-radius: 50%;
  transition: transform var(--duration-fast) var(--ease-out);
}
.ei-inviter__sigil-link:hover { transform: translateY(-1px); }
.ei-sigil {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 2px solid var(--color-gold);
  background: linear-gradient(135deg, var(--color-navy), var(--color-cyan));
  color: var(--color-cream);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.02em;
}
.ei-sigil img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
}
.ei-inviter__name {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 14px;
  color: var(--color-navy);
  text-decoration: none;
}
/* Per Rob 28/06/26: no gold-on-hover for names. Match the My Interests pop
   affordance — inviter name scales 1.07x on hover. */
.ei-inviter__name { display: inline-block; transition: transform var(--duration-fast) var(--ease-out); }
a.ei-inviter__name:hover { transform: scale(1.07); color: var(--color-navy); text-decoration: none; }
.ei-inviter__meta {
  font-size: 12px;
  /* Gold per Rob 28/06/26. */
  color: var(--color-gold);
}

/* §67.3 Event details */
/* Venue line — bottom of the title/date/venue "sandwich". Per Rob 28/06/26:
   same size + weight + colour as the title (navy heading), so the sandwich
   reads blue (title) → gold (date) → blue (venue). !important locks colour
   across all states (Seeko's a:hover would otherwise shift to gold-dark). */
.ei-venue {
  font-family: var(--font-heading);
  font-size: 16px;
  font-weight: 700;
  color: var(--color-navy) !important;
  text-align: center;
  /* Flex row so the brand pin sits inline with the venue name and the line
     stays centred. Gap matches the My Interests location-line spacing. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
/* §67.3.1 Brand pin inside the invite venue line. The base `.mi-pin-icon` is
   sized for 13px text on My Interests (16px tall, drawn whole by `contain`). The
   invite venue runs at 16px / heading-bold, so the pin scales up to 20px tall
   to stay proportional, with the vertical nudge re-tuned to its taller box.
   S245, the 9th of October 2026, FAULTS 145 (Rob: "the platform's mapping logo is completely cut off. This has happened many times across the
   platform. Screenshot three is what it should look like."). The box was 12.6 x 20 with `background-size: 20px auto`, which paints the 137 x 192
   pin PNG at 20 x 28 and shows only its middle: the two heads and the gold X were cut off (MEASURED at deviceScaleFactor 8). The box is now the
   PNG's own proportion at the same 20px height, 20 x 137 / 192 = 14.27px, and the size is `contain`, exactly as the base .mi-pin-icon (21360) and
   .invite-event-card-pin have it, so the whole mark paints, top to bottom, and no box can crop it. The nudge below is unchanged: the whole mark's ink
   midpoint measures 0.25px above the first capital's band centre at 1280 and 360 (deviceScaleFactor 8), the same as the cropped one did. */
.ei-venue .ei-pin {
  width: 14.27px;
  height: 20px;
  background-size: contain;
  /* Measured: at 16px heading-bold, the pin ink centre lands +0 from the text
     ink cap-centre when nudged down 4px from its baseline alignment. */
  transform: translateY(4px);
  /* Flex `gap` doesn't apply between a flex-item element and a bare text-node
     sibling in Chrome, so the gap has to live on the pin itself. Matches the
     6px gap on the My Interests location line. Per Rob 28/06/26. */
  margin-right: 6px;
}
/* Inviter's personal note */
.ei-message {
  margin: var(--sp-xs) 0 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--color-text-secondary);
  text-align: center;
  text-wrap: pretty;
}
/* S233 (invite-submit, FAILED): the shared hobbies the sender picked on the invite form. They
   were stored on the invite and never rendered, so the one promise the picker makes to the sender
   ("so they know what you have in common") was never kept on the receiving side. The chips
   themselves are the platform's own .att-chip--reserved shape; this rule only lays the row out,
   centred like every other independent block in the workspace (D105). */
.ei-hobbies {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  margin: var(--sp-sm) 0 0;
}
.ei-hobbies__label {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 600;
  color: var(--color-text-secondary);
  text-align: center;
}
.ei-hobbies__chips {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
}

/* On the card, clamp long messages to two lines (full text in the modal). */
.ei-message--clamp {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* The att-res-card top should sit directly under the inviter header */
.att-res-card .ei-inviter + .att-res-card__top {
  margin-top: 0;
}

/* S245, the 9th of October 2026, T-S229-018 (c) (Rob, the 15th of September 2026: "the Minimum proximity distance pin must be the SITE'S map pin
   icon, uncropped, with the heads visible at the top and the gold X at the bottom"). The head of the proximity panel on this page
   (invite-system.php 2977) draws a generic outline map pin as an inline <svg class="ei-proximity__icon">, 20 x 20, stroked in #CC9900 by that
   file's own `.ei-proximity__icon { color }`: it is not the site's pin. It paints the site pin now, whole: the same PNG, `contain` and 20px height
   as the invite venue pin above (.ei-venue .ei-pin), in the box the pin's own proportion makes (20 x 137 / 192 = 14.27px). The inline drawing's shapes
   are not painted, so only the site pin shows. The title stays where it was to within half a pixel: the gap from the pin's ink to the title's first letter
   is the 8px flex gap plus 3px here, because the site pin's ink fills its box where the old outline pin left 3.6px of empty box beside it (MEASURED at
   deviceScaleFactor 8, 1280 and 360: 12.63px before, 12.13px after). The row is centred and the box snaps to a whole pixel, so the gap steps from 12.4px
   to 13.5px as this margin passes 3.5px and none lands exactly on the 12.75px that TICK-1 matched the tick boxes to; 3px keeps it inside half a pixel of
   where it was, well clear of the step. If the markup is ever swapped for
   <span class="mi-pin-icon ei-proximity__icon" aria-hidden="true"></span>, the last rule below is simply never matched. */
.ei-proximity__head .ei-proximity__icon {
  width: 14.27px;
  height: 20px;
  background: url('https://uksocials.club/wp-content/uploads/2025/05/uks-site-pin.png') center / contain no-repeat;
  margin-right: 3px;
}
.ei-proximity__head .ei-proximity__icon > * { display: none; }

/* §67.3.1 Event title colour — navy on card and modal, matching the design
   source (the shared .att-res-card shell title, no gold-dark shift on hover). */
.workspace .ei-panel .att-res-card__name,
.workspace .ei-panel .att-res-card__name:hover {
  color: var(--color-navy);
  text-decoration: none;
}

/* §67.4 Larger panel that holds the card grid (matches the other pages' sections).
   align-content: start so the animated height during a paged scroll doesn't
   spread the rows; overflow-anchor: none kills the browser scroll-anchor jolt. */
.ei-panel { padding: var(--sp-xl); overflow-anchor: none; }
.ei-grid { align-content: start; overflow-anchor: none; }

/* Cards need a visible resting shadow so they read as cards on the white panel
   (the panel and card are both white; --shadow-sm alone is invisible here). */
.ei-panel .att-res-card {
  box-shadow: 0 4px 16px rgba(3, 27, 131, 0.12), 0 1px 4px rgba(3, 27, 131, 0.08);
}
.ei-panel .att-res-card:hover {
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.22), 0 2px 8px rgba(3, 27, 131, 0.10);
}

/* S245, the 9th of October 2026, FAULTS 144 (found by the Opus invites agent after row 142). The card opens nothing now that the pop-up is gone
   (invite-system.php 3220 to 3223: no role, no tabindex, no click handler), so it takes NO pointer cursor and NO focus outline. The two rules that
   stood here, `.ei-card-clickable { cursor: pointer; }` and `html[data-nav="kbd"] .ei-card-clickable:focus-visible { outline: 2px solid gold }`,
   are removed, not overridden. The class stays on the card ONLY because 67.3a below paints the card's date gold through it, which is unchanged.
   The title link, the venue link and the inviter's links keep the browser's own link cursor; the buttons keep theirs. */
/* Profile links inside the card keep their own pointer + don't trigger open. */
.ei-inviter__sigil-link, .ei-inviter__name { position: relative; z-index: 1; }

/* §67.5 Body grows so the foot pins to the bottom; foot is a FIXED-height block so
   the divider + buttons sit at the same place on every card regardless of the
   message length above. */
.ei-panel .att-res-card__top { flex: 1 1 auto; }
.ei-foot {
  flex: 0 0 auto;
  min-height: 60px;
  margin-top: var(--sp-md);
}

/* S229 VC10, Rob: Option B on every invite card. The response buttons share the approved 40px height and centre when stacked.
   S245, the 9th of October 2026, FAULTS 146 (LB-529, a button is fixed in its GROUP; Rob: "you can very clearly see that the decline button is bigger than
   the accept button"). They no longer keep their own natural widths: they are ONE size. MEASURED live at 1280 and 360: Accept 93.66 x 40 and
   Decline 97.72 x 40 (the labels are 53.66 and 57.72 wide at 12px / 700 / 0.06em, plus the 18px padding and the 2px ring each side), so Decline stood 4.06px
   wider. Both take the width of the wider one rounded up to the pixel, 98px, which is how the site already makes its card-foot pills one width (.att-chip,
   min-width 96px, S244 row 123: "4.2px above the widest label, so every pill is one width"). Nothing else changes: the cream and red grounds, the ring, the ONE
   shadow --shadow-gold-hover at rest and hovered, none and the darker ground when held, the 10px corners and the 40px height are the canonical
   .btn--primary and .btn--danger ones (MEASURED in every state, none needed changing). Side by side and stacked, the pair centres as before. */
.workspace .ei-action-form .att-cancel-btn {
  min-height: 40px;
  min-width: 98px;
}
@media (max-width: 599.98px) {
  .workspace .ei-action-form {
    flex-direction: column;
    align-items: center;
  }
}

/* Fake footer to keep document height constant during paged-shrink scroll. R3-12 (24/09/2026):
   it holds height only while the invites can page (the pagination is showing). The rest of the
   time it was a 600px empty band under Event Invites, where every other dashboard page ends
   30px above the footer. */
.app:has([data-ei-pag]:not([style*="none"])) ~ .ei-page-pad { height: 600px; }

/* §67.5.1 Modal foot spacing symmetry — the .att-res-card__foot inheritance
   adds margin-top + border-top + padding-top from --sp-md, which doubled the
   gap above the divider. Wiped to zero/20 inside the modal so the divider sits
   evenly between the message and the buttons. */
.ei-modal__card .ei-foot {
  margin-top: 0;
  padding-top: 20px;
}

/* §67.5.3 Destination-pill count pulse — when a card moves to its new tab
   the destination count bubble briefly scales up so the user sees their
   card "land" in the right place. */
@keyframes ei-pill-pulse {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.3); }
  100% { transform: scale(1); }
}
.ei-menu-count.ei-pulse {
  animation: ei-pill-pulse 500ms ease-out;
}

/* Empty-state line-art glyph (replaces off-brand emoji) */
.ei-empty-glyph { color: var(--color-gold); }

/* §67.6 Invite detail modal */
.ei-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-xl);
  background: rgba(3, 27, 131, 0.35);
  -webkit-backdrop-filter: blur(3px);
          backdrop-filter: blur(3px);
  animation: ei-modal-fade 160ms var(--ease-out);
}
@keyframes ei-modal-fade { from { opacity: 0; } to { opacity: 1; } }
.ei-modal__card {
  position: relative;
  width: 100%;
  max-width: 460px;
  max-height: 86vh;
  overflow-y: auto;
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  padding: var(--sp-2xl) var(--sp-xl) var(--sp-xl);
  display: flex;
  flex-direction: column;
  gap: var(--sp-lg);
  animation: ei-modal-pop 180ms var(--ease-out);
}
/* Modal body wrapper is structural-only — display:contents lifts its children
   into the .ei-modal__card flex container so the uniform 24px gap applies
   between every section (inviter / event details / pills / status). */
.ei-modal__card > [data-ei-modal-body] {
  display: contents;
}
@keyframes ei-modal-pop { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
.ei-modal__close {
  position: absolute;
  top: 12px;
  right: 12px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  /* padding: 0 added 25/06/26 to defeat parent-theme seeko-dynamic.css
     `button { padding: 0.5rem 1rem }` which was squashing the inner SVG to
     width 0. Design's prototype CSS reset zeros button padding by default;
     live theme doesn't. This restores the design's intent. */
  padding: 0;
  border-radius: 50%;
  border: 1.5px solid var(--color-gold);
  background: var(--color-surface);
  color: var(--color-navy);
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out);
}
.ei-modal__close:hover { background: var(--color-cream); }
.ei-modal__status {
  margin: 0;
  text-align: center;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 13px;
  padding-top: var(--sp-lg);
  border-top: 1px solid rgba(204, 153, 0, 0.35);
}
.ei-modal__status--ok { color: var(--color-success); }
.ei-modal__status--no { color: var(--color-error); }

/* §67.7 Red Declined chip (Attendance has no red chip variant) */
.ei-chip--declined {
  background: var(--color-error-bg);
  color: var(--color-error);
  border-color: var(--color-error);
}

/* end of §67 */


/* ============================================================================
   §67.8 Event Invite popover — clickable date line. The date opens the member's
   dashboard at that date so they can see what other events they have on. Slight
   "pop" affordance on hover; navy stays navy (no theme gold hover). Per Rob
   28/06/26.
   ============================================================================ */
.ei-when-link {
  display: inline-block;
  color: inherit;
  text-decoration: none;
  transition: transform var(--duration-fast) var(--ease-out);
}
.ei-when-link:hover { transform: scale(1.07); color: inherit; }

/* §67.3a Invite date — middle of the title/date/venue "sandwich". Gold per
   Rob 28/06/26 so the popover reads blue → gold → blue. Scoped to invite
   contexts (card + modal) so Attendance pages stay untouched. !important locks
   the colour across the link's hover/focus too (Seeko's a:hover would shift it). */
.ei-card-clickable .att-res-card__when,
#ei-modal .att-res-card__when,
.ei-card-clickable .att-res-card__when .ei-when-link,
#ei-modal .att-res-card__when .ei-when-link {
  color: var(--color-gold) !important;
}

/* §67.8 Invite popover — title (event page link) and venue (Google Maps link)
   get the same pop affordance as the date and inviter name. Per Rob 28/06/26:
   members should be able to click straight through from any invite to the
   event, the inviter's profile, or the venue location — all in new tabs. */
a.att-res-card__name,
a.ei-venue {
  display: inline-block;
  text-decoration: none;
  transition: transform var(--duration-fast) var(--ease-out);
}
a.att-res-card__name { color: var(--color-navy); }
a.att-res-card__name:hover,
a.ei-venue:hover { transform: scale(1.07); }
/* No colour change on venue hover — the .ei-venue rule above is !important so
   the rest-state gold sticks across hover/focus/active. Pop only. */

/* ============================================================================
   §67.9 GLOBAL — no underline on link hover/focus. Per Rob 28/06/26: the
   theme/browser default underline-on-hover for links looks wrong site-wide;
   suppress it everywhere. !important so it beats Seeko / BuddyPress / Bootstrap
   hover rules regardless of their specificity.
   ============================================================================ */
a:hover,
a:focus { text-decoration: none !important; }

/* ============================================================================
   §68 My Interests — design-agent port (2026-06-27)
   Ported verbatim from design_handoff_my_interests/design/myinterests.css.
   Scope-bumps added where Seeko / BuddyPress / inline footer styles would
   otherwise paint our buttons (see §68.x scope-bump blocks at the end).
   ============================================================================ */

/* §68.0 Container-query root.
   The design ships a `mic` container on .workspace so the panel can resize
   independently of viewport (stable across the 1023px sidenav collapse).
   We scope to .mi-workspace so this only applies on My Interests and never
   interferes with other dashboard workspaces. */
.mi-workspace {
  max-width: 992px;
  margin-inline: auto;
  container-type: inline-size;
  container-name: mic;
}

/* §68.1 Header — subtitle wrap + gold hairline rule (mirror of .rep-* / .ev-*) */
.mi-subtitle-wrap {
  display: table;
  margin: 0 auto;
}
.mi-subtitle-wrap .workspace__subtitle {
  display: block;
  margin-bottom: var(--sp-sm);
}
.mi-header-rule {
  width: 100%;
  height: 1.5px;
  background: var(--color-gold);
  border-radius: var(--radius-pill);
  margin-top: var(--sp-sm);
}

/* §68.2 Section panel — constant width per breakpoint; cards centre inside */
.mi-section {
  --mi-panel-w: 970px;
  --mi-cols: 3;
  width: var(--mi-panel-w, 970px);
  max-width: 100%;
  margin: 0 auto var(--sp-xl);
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: var(--sp-2xl);
  box-shadow: var(--shadow-sm);
  overflow-anchor: none;
}

/* §68.2.1 Tab menu count bubble (cream fill, gold border, navy number) — on
   the SectionNav gold pills. The "active" pill flips the bubble to white so
   the number reads on the gold fill. */
.mi-menu-label {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}
.mi-menu-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  /* S220 14/09/2026, Rob on a phone: "this venues label and badge at the end with the number it
     doesn't look properly centered vertically. The number definitely isn't within the badge?"
     MEASURED at 390 and he is right on both counts. (1) The number sat 1.000px HIGH in its own
     bubble, because the 1px of BOTTOM padding shortened the content box upward; the padding is now
     1px top and 0 bottom, which moves it down by exactly that 1px. (2) The sides were 5.5 left and
     4.5 right, so different digits landed differently; they are level at 5px. */
  padding: 1px 5px 0;
  /* (3) The bubble itself sat 1.391px BELOW the letters of the word beside it, because an
     inline-flex bubble aligns on the text baseline rather than on the letters. Measured lift. */
  position: relative;
  top: -1.391px;
  border-radius: var(--radius-pill);
  background: var(--color-cream);
  border: 1.5px solid var(--color-gold);
  color: var(--color-navy);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
}
.section-nav__item--active .mi-menu-count {
  background: var(--color-surface);
}

/* §68.3 Card grid — fixed-width cards, flex-wrap + centre; full row fills the
   panel edge-to-edge and a partial last row centres in its row.
   align-content:flex-start REQUIRED for the smooth-on-shrink height animation. */
.mi-grid {
  --mi-card-w: 290px;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-content: flex-start;
  gap: var(--sp-lg);
  overflow-anchor: none;
}
.mi-grid--solo { justify-content: center; }

/* §68.4 Person / entity card — vertical layout (Sigil → name → since/loc → Withdraw) */
.mi-card {
  flex: 0 0 var(--mi-card-w);
  width: var(--mi-card-w);
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--sp-sm);
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: var(--sp-xl) var(--sp-lg) var(--sp-lg);
  text-decoration: none;
  box-shadow: 0 4px 16px rgba(3, 27, 131, 0.12), 0 1px 4px rgba(3, 27, 131, 0.08);
  transition: transform var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out);
}
.mi-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.22), 0 2px 8px rgba(3, 27, 131, 0.10);
  text-decoration: none;
}
html[data-nav="kbd"] .mi-card:focus-visible { outline: 2px solid var(--color-gold); outline-offset: 2px; }
.mi-card.is-removing {
  opacity: 0;
  transform: scale(0.94);
  transition: opacity var(--duration-normal) var(--ease-out),
              transform var(--duration-normal) var(--ease-out);
  pointer-events: none;
}
/* §68.4a Entity card head — sigil + name as one link to the on-platform venue
   page (opens new tab). Replicates the card's centred column so the split
   (name link + separate Maps link) keeps the original single-anchor layout.
   Per Rob 28/06/26: the link hugs its content (sigil + name) — was width:100%
   which made the click area stretch the full card width, leaving members
   accidentally clicking through from the empty card sides. */
.mi-card__head {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-sm);
  text-decoration: none;
  color: inherit;
}
/* No colour change on hover for the card name/location — the card lift is the
   affordance. Per Rob 28/06/26: names/links must not go gold on hover. */
html[data-nav="kbd"] .mi-card__head:focus-visible,
html[data-nav="kbd"] .mi-card__loc:focus-visible {
  outline: 2px solid var(--color-gold);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* §68.5 Sigil — circular wrapper. When real image present, .mi-sigil > img
   fills the circle via object-fit. When initials-only fallback, gradient bg
   + cream text shows through. */
.mi-sigil {
  width: 60px;
  height: 60px;
  border-radius: 50%;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 19px;
  letter-spacing: 0.02em;
  color: var(--color-cream);
  background: linear-gradient(135deg, var(--color-navy), var(--color-cyan));
  border: 2.5px solid var(--color-gold);
  box-shadow: 0 3px 10px rgba(2, 22, 106, 0.22);
  margin-bottom: var(--sp-xs);
  overflow: hidden;
}
.mi-sigil > img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  display: block;
}
/* Entity (venue / organiser) Sigil — gold-on-navy + square-ish so it reads
   as a place / brand rather than a person. */
.mi-sigil--entity {
  border-radius: var(--radius-md);
  color: var(--color-gold);
  background: linear-gradient(145deg, #2a3556, #1f2848);
}
.mi-sigil--entity > img {
  border-radius: var(--radius-md);
}

.mi-card__name {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 16px;
  line-height: 21px;
  color: var(--color-navy);
  text-wrap: balance;
  display: inline-block;
  transition: transform var(--duration-fast) var(--ease-out);
}
/* Slight "pop" on hover so the name reads as clickable (per Rob 28/06/26) — no
   colour change. The whole card also lifts; this is the per-link affordance. */
.mi-card__head:hover .mi-card__name { transform: scale(1.07); }

/* §68.6 Entity type tag (Venue / Organiser) */
.mi-tag {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-navy);
  background: rgba(204, 153, 0, 0.12);
  border: 1px solid rgba(204, 153, 0, 0.5);
  border-radius: var(--radius-pill);
  padding: 4px 10px 3px;
  line-height: 1;
}

/* §68.7 Since / date meta line. Whole-pixel line-heights keep each card an
   integer height so every row lands on the same sub-pixel offset (no 1px
   row-to-row Withdraw drift). */
.mi-card__since {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 12px;
  color: var(--color-gold);
  line-height: 16px;
  display: inline-block;
  text-decoration: none;
  /* Optical balance: the date→Withdraw gap reads tighter than the other rows.
     Per Rob 28/06/26: settled at 7px (was 9px, dropped 2px). Total visible gap
     is now ~15px (8px flex gap + 7px margin). */
  margin-bottom: 7px;
}

/* §68.7 Location line — a link to Google Maps (opens new tab). Secondary-text
   look at rest. Per Rob 28/06/26: NO gold on hover (Seeko's a:hover sets gold);
   instead a slight "pop" so it reads as clickable. */
.mi-card__loc {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 13px;
  color: var(--color-text-secondary);
  line-height: 17px;
  text-decoration: none;
  transition: transform var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out);
}
.mi-card__loc:hover { color: var(--color-text-secondary); transform: scale(1.07); }

/* §68.7.1 Brand map-pin — the site's brand mark (the map-pin logo used as the
   favicon / app icon site-wide). Per Rob 2026-06-28: use the actual brand pin.
   The pin's ink sits centred in its square image with ~35/192 transparent
   padding each side; left as a 16px box that padding is dead space INSIDE the
   centred location line, pushing the ink ~1.45px right of the card centre. Fix:
   render the mark at 16px but clip the box to the pin's ink width (~10.2px) and
   centre the image, so the box hugs the ink and the line centres on its ink. */
.mi-pin-icon {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  display: inline-block;
  /* S222 14/09/26, ICON1. Rob on the site pin (item 111): "everywhere this icon is used, it
     should be the full icon". Same artwork, white keyed to alpha and the file's own padding
     cropped off, so the 16px box paints 16.00px of ink instead of 14.25px (measured at dpr 8)
     and the mark can sit on cream without a white square behind it. The ink midpoint is 7.94
     before and after, so the translateY below is unchanged. */
  background-image: url('https://uksocials.club/wp-content/uploads/2025/05/uks-site-pin.png');
  background-repeat: no-repeat;
  background-size: contain;
  background-position: center;
  /* The 16px-tall pin box centres on the text line-box, but the text's cap-band
     reads ~1.5px higher, so the pin looks low. Lift it onto the text ink. */
  transform: translateY(-1.5px);
}

/* §68.7.9 On-brand confirm modal — replaces browser-native confirm()/alert()
   for the Withdraw flow. White card, gold border, navy heading text, cancel
   pill + red "Yes, withdraw" pill. Centred over a translucent navy backdrop.
   Per Rob 28/06/26 (never use grey WordPress dialogs). */
.mi-confirm {
  position: fixed; inset: 0; z-index: 100000;
  display: flex; align-items: center; justify-content: center;
  padding: var(--sp-lg);
}
.mi-confirm[hidden] { display: none; }
.mi-confirm__backdrop {
  position: absolute; inset: 0;
  background: rgba(3, 27, 131, 0.45);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}
.mi-confirm__card {
  position: relative;
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-lg, 14px);
  box-shadow: 0 18px 50px rgba(3, 27, 131, 0.28), 0 4px 14px rgba(3, 27, 131, 0.12);
  padding: var(--sp-2xl) var(--sp-xl) var(--sp-xl);
  max-width: 380px;
  width: 100%;
  text-align: center;
  animation: mi-confirm-in 180ms var(--ease-out, ease-out);
}
@keyframes mi-confirm-in {
  from { opacity: 0; transform: translateY(-6px) scale(0.98); }
  to   { opacity: 1; transform: none; }
}
.mi-confirm__msg {
  margin: 0 0 var(--sp-xl);
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 16px;
  line-height: 1.4;
  color: var(--color-navy);
}
.mi-confirm__actions {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-md);
  flex-wrap: wrap;
}
.mi-confirm__btn {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1;
  padding: 9px 16px 8px;
  border-radius: var(--radius-pill);
  border: 2px solid var(--color-gold);
  background: transparent;
  color: var(--color-navy);
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out);
}
.mi-confirm__btn--cancel:hover {
  background: var(--color-cream, #FFF9E6);
  /* Seeko's `button:hover` strips the border-color to transparent — restate it
     so the gold ring stays on hover. Per Rob 28/06/26. */
  border-color: var(--color-gold);
  color: var(--color-navy);
  /* Same pop affordance as every other clickable on the site. */
  transform: scale(1.07);
}
.mi-confirm__btn--ok {
  border-color: var(--color-error);
  color: var(--color-error);
}
.mi-confirm__btn--ok:hover {
  background: var(--color-error);
  color: #fff;
  box-shadow: 0 4px 10px rgba(196, 28, 28, 0.24);
  transform: scale(1.07);
}
/* Press-down affordance on click, matching `.mi-withdraw-btn:active`. */
.mi-confirm__btn:active { transform: translateY(1px); box-shadow: none; }
/* No custom focus ring — the browser default outline shows for real keyboard
   tab focus, which is enough. Per Rob 28/06/26. */

/* §68.8 Withdraw button — gentle danger pill (mirrors Wish List "Remove").
   Pins to card bottom so every button bottom-aligns regardless of content. */
.mi-withdraw-btn {
  margin-top: auto;
  align-self: center;
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1;
  padding: 9px 16px 8px;
  border-radius: 10px;
  border: 2px solid var(--color-error);
  background: transparent;
  color: var(--color-error);
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out);
}
.mi-withdraw-btn:hover {
  background: var(--color-error);
  color: #fff;
  border-color: var(--color-error);
  box-shadow: 0 4px 10px rgba(196, 28, 28, 0.24);
}
.mi-withdraw-btn:active { transform: translateY(1px); box-shadow: none; }
/* The X icon sits next to the uppercase "WITHDRAW" label. Nudge it down onto
   the text ink centre. Per Rob 2026-06-28: the previous -0.77px lift read too
   high, so move it down one pixel (now translateY(0.23px)). Global across all
   Withdraw buttons in every tab and row. */
.mi-withdraw-btn svg { display: block; transform: translateY(0.23px); }

/* Spacer to keep non-button cards the same height as button cards in the
   same row when both are present. */
.mi-card__spacer { flex: 1 1 auto; min-height: 4px; }

/* §68.9 Section empty state (one tab cleared) */
.mi-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-md);
  text-align: center;
  padding: var(--sp-2xl) var(--sp-xl);
}
.mi-empty__glyph {
  color: var(--color-gold);
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 46px;
  line-height: 1;
}
/* Platform entity icons in the empty-state slot need explicit sizing: the member
   SVG (hard-coded 16x16) and the venue/organiser dashicons would otherwise
   render tiny. 46px matches the old emoji footprint; colour inherits gold from
   the rule above (SVG stroke=currentColor; dashicons use color). */
.mi-empty__glyph svg { width: 46px; height: 46px; }
.mi-empty__glyph .dashicons { width: 46px; height: 46px; line-height: 1; }
.mi-empty__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 16px;
  color: var(--color-navy);
  margin: 0;
}
.mi-empty__hint {
  font-size: 13px;
  color: var(--color-text-secondary);
  line-height: 1.6;
  text-wrap: pretty;
  margin: 0;
  max-width: 360px;
}
.mi-empty__cta {
  font-family: var(--font-heading);
  font-size: 13px;
}
.mi-link {
  color: var(--color-gold-dark);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1.5px;
}
.mi-link:hover { color: var(--color-gold); }

/* §68.10 Pagination (mirrors Attendance / Wish List / Event Invites) */
.mi-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-lg);
  margin-top: var(--sp-xl);
}
.mi-pagination__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1.5px solid var(--color-gold);
  background: var(--color-surface);
  color: var(--color-navy);
  cursor: pointer;
  padding: 0;
  transition: background var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-out);
}
.mi-pagination__btn:hover:not(:disabled) { background: var(--color-cream); transform: scale(1.08); }
.mi-pagination__btn:disabled { opacity: 0.3; cursor: default; }
.mi-pagination__btn svg { display: block; }
.mi-pagination__info {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 13px;
  color: var(--color-navy);
}

/* §68.11 Panel width tracks the workspace's REAL width (mic container) */
@container mic (max-width: 969px) {
  .mi-section { --mi-panel-w: 664px; --mi-cols: 2; }
}
@container mic (max-width: 663px) {
  .mi-section { --mi-panel-w: 358px; --mi-cols: 1; }
}

/* §68.12 Narrow viewport polish — vp container is set globally at §42.0 on
   body.profile-dashboard-active:not(.profile-editor-active) #item-body */
@container vp (max-width: 640px) {
  .mi-section { padding: var(--sp-xl) var(--sp-lg); }
}

/* ── §68.x SCOPE-BUMPS — defeat Seeko / BuddyPress / inline-footer rules ──── */

/* §68.20 Seeko's `button { margin-bottom: 1rem; padding: 0.5rem 1rem; border;
   font-size; line-height; ... }` and `button:hover { background-color: #f0f0f0;
   color: #191919; border-color: transparent }` will paint our pills if not
   defeated. Per /design-implementation Rule 12 (specificity wins PER-PROPERTY)
   set EVERY property the theme rule sets, with !important to defeat the
   theme's !important on .btn-and-friends. */
#buddypress .mi-workspace .mi-withdraw-btn,
#buddypress .mi-workspace .mi-pagination__btn {
  margin-bottom: 0 !important;
}
#buddypress .mi-workspace .mi-withdraw-btn {
  padding: 9px 16px 8px !important;
  border: 2px solid var(--color-error) !important;
  background: transparent !important;
  color: var(--color-error) !important;
  font-size: 12px !important;
  line-height: 1 !important;
}
#buddypress .mi-workspace .mi-withdraw-btn:hover {
  background: var(--color-error) !important;
  color: #fff !important;
  border-color: var(--color-error) !important;
}
#buddypress .mi-workspace .mi-pagination__btn {
  padding: 0 !important;
  border: 1.5px solid var(--color-gold) !important;
  background: var(--color-surface) !important;
  color: var(--color-navy) !important;
  width: 36px !important;
  height: 36px !important;
  font-size: 13px !important;
  line-height: 1 !important;
}
#buddypress .mi-workspace .mi-pagination__btn:hover:not(:disabled) {
  background: var(--color-cream) !important;
  color: var(--color-navy) !important;
  border-color: var(--color-gold) !important;
}

/* §68.21 The SectionNav gold pills already exist (§42.2) and survive Seeko's
   button rules via their own scope-bumps. The .mi-menu-count bubble sitting
   inside the pill label is unaffected — it's a span, not a button. */

/* end of §68 */


/* ============================================================================
   §69 Add an Event — design-agent port (2026-06-27)
   Ported verbatim from design_handoff_addevent/design/addevent.css.
   Scope-bumps for Seeko `input` + `button` + `textarea` rules added at §69.x.
   ============================================================================ */

/* §69.0 Page column (replaces .workspace) — only on the Add Event surface. */
.ev-page {
  max-width: 720px;
  margin-inline: auto;
  width: 100%;
  /* Top padding zeroed so the Back-to-my-events button aligns with the top
     of the sidenav. The sidenav has no top padding of its own. Per Rob 28/06/26. */
  padding: 0 var(--sp-xl) var(--sp-4xl);
  container-type: inline-size;
  container-name: evp;
}

/* §69.1 Page header */
.ev-head {
  text-align: center;
  margin-bottom: var(--sp-2xl);
}
.ev-head__back {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-navy);
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-pill);
  padding: 8px 16px 8px 12px;
  margin-bottom: var(--sp-xl);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
  transition: background var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-out);
  text-decoration: none;
}
.ev-head__back:hover { background: var(--color-cream); transform: translateX(-2px); text-decoration: none; }
.ev-head__back svg { display: block; }
.ev-head__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 30px;
  line-height: 1.15;
  color: var(--color-navy);
  margin: 0;
}
.ev-head__sub-wrap { display: table; margin: var(--sp-md) auto 0; }
.ev-head__sub {
  display: block;
  font-size: 15px;
  color: var(--color-text-secondary);
  line-height: 1.55;
  text-wrap: pretty;
}
.ev-head__rule {
  display: block;
  width: 100%;
  height: 1.5px;
  margin-top: var(--sp-md);
  background: var(--color-gold);
  border-radius: var(--radius-pill);
}

/* §69.2 Card (panel) */
.ev-card {
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  padding: var(--sp-2xl);
  text-align: center;
}
.ev-card + .ev-card { margin-top: var(--sp-xl); }
.ev-card__head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-lg);
  margin-bottom: var(--sp-lg);
}
/* S231 18/09/26 (triage item 16). Rob first: "remove the numbers and remove the pills". The
   numbered badge came from the Add Event design handoff (addevent.jsx line 616) and was ported
   verbatim in S117 on 27/06/26; the pill, the badge and the optical-centring JS that served it are
   all gone. Rob then: "just make the titles the same as they are on the single event page. with
   the I think it is more bold, font, bigger letters, drop shadow, gold underline, that kinda thing.
   Just copy it exactly from the single event page." So the declarations below are copied from
   .event-card__title (event-page.css 5.6) character for character, with margin-inline:auto added
   because display:table on a centred card would otherwise sit the title on the left. The gold
   spacer that briefly sat above the title is gone: the copied title brings its own gold rule, and
   two gold lines per section is one too many. */
.ev-card__title {
  font-family: var(--font-heading);
  font-size: 36px;
  color: var(--color-navy);
  font-weight: 700;
  margin: 10px auto calc(var(--sp-lg) + 5px);
  padding-bottom: 8px;
  border-bottom: 2px solid var(--color-gold);
  display: table;
  text-shadow: 0 4px 6px rgba(3,27,131,.18), 0 2px 4px rgba(3,27,131,.12);
}
.ev-card__hint {
  font-size: 13px;
  color: var(--color-text-secondary);
  line-height: 1.5;
  max-width: 440px;
  margin: 0;
  text-wrap: pretty;
}

/* §69.3 Field */
.ev-field {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-sm);
}
.ev-field + .ev-field,
.ev-row + .ev-field { margin-top: var(--sp-xl); }
.ev-label {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-navy);
  text-align: center;
}
.ev-label__opt {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 12px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--color-text-muted);
  margin-left: 6px;
}
.ev-req { color: var(--color-gold-dark); margin-left: 2px; }

/* §69.4 Inputs / textareas */
.ev-input,
.ev-textarea {
  width: 100%;
  max-width: 460px;
  padding: 12px 14px;
  font: 400 15px var(--font-body);
  color: var(--color-navy);
  background: var(--color-surface);
  border: 2px solid var(--color-gold);
  border-radius: var(--radius-md);
  outline: none;
  color-scheme: light;
  transition: box-shadow var(--duration-fast) var(--ease-out);
  box-sizing: border-box;
}
.ev-input { text-align: center; padding-top: 11px; padding-bottom: 13px; }
/* Placeholder colour — bumped from 42% to 70% navy per Rob 28/06/26 so it
   reads on-brand (was washed out / appeared grey on the light background). */
/* Placeholders — one consistent, clearly-a-placeholder navy across every event
   form field. Scoped to .ev-page + !important so it wins over the browser/theme
   default grey that was leaking onto the text inputs (left them grey while the
   textareas were near-black at 70% — inconsistent). 55% reads as a placeholder,
   not real text. (Rob 29/06/26.) */
.ev-page .ev-input::placeholder,
.ev-page .ev-textarea::placeholder,
.event-refund-req .ev-textarea::placeholder { color: rgba(3, 27, 131, 0.65) !important; font-style: italic; text-align: center; }
html[data-nav="kbd"] .ev-input:focus,
html[data-nav="kbd"] .ev-textarea:focus { box-shadow: 0 0 0 2px rgba(204, 153, 0, 0.25); }
.ev-textarea {
  text-align: center;
  line-height: 1.55;
  resize: vertical;
  min-height: 64px;
}
.ev-textarea--short { height: 132px; resize: none; overflow: hidden; }
/* Taller on load so the whole placeholder is readable at 360, and overflow:auto
   (not hidden) so the resize grabber is visible in the bottom-right. (Rob 29/06/26.) */
.ev-textarea--tall { min-height: 170px; overflow: auto; resize: vertical; }

/* §69.5 Number stepper */
.ev-num { position: relative; width: 100%; max-width: 460px; }
.ev-num__input {
  width: 100%;
  max-width: none;
  padding-left: 38px;
  padding-right: 38px;
  -moz-appearance: textfield;
  appearance: textfield;
  /* Kill the theme's 16px input margin-bottom — it inflated .ev-num's height so
     the absolutely-centred up/down arrows dropped ~8px and the down chevron poked
     out the bottom of the pill. (Rob 29/06/26.) */
  margin-bottom: 0 !important;
}
.ev-num__input::-webkit-outer-spin-button,
.ev-num__input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.ev-num__steps {
  position: absolute;
  right: 7px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: 3px;
}
/* Borderless chevrons so they sit cleanly INSIDE the rounded pill instead of
   reading as a separate gold box poking out past the 16px-radius right corner.
   (Rob 29/06/26 — "arrows on the ticket counters not in the pills properly".) */
.ev-num__btn {
  width: 22px;
  height: 15px;
  display: grid;
  place-items: center;
  padding: 0;
  border: none;
  background: transparent;
  /* Gold chevrons to match the dropdown arrows. (Rob 29/06/26.) */
  color: var(--color-gold);
  border-radius: 4px;
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out);
  margin-bottom: 0;
}
.ev-num__btn:hover { background: var(--color-cream-hover); color: var(--color-gold); }
.ev-num__btn:active { background: var(--color-cream); }
.ev-num__btn svg { display: block; }

.ev-input[type="date"],
.ev-input[type="time"],
.ev-input[type="number"] { text-align: center; }

.ev-charcount {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 12px;
  color: var(--color-text-muted);
}
.ev-charcount--over { color: var(--color-error); }

.ev-note {
  font-size: 13px;
  color: var(--color-text-secondary);
  line-height: 1.55;
  max-width: 460px;
  margin: 2px auto 0;
  text-wrap: pretty;
}
/* Links in form notes (e.g. "Connect your Stripe account") stay gold on hover —
   Seeko's a:hover turns them near-black. (Rob 29/06/26.) */
.ev-note a { color: var(--color-gold); }
.ev-note a:hover,
.ev-note a:focus { color: var(--color-gold) !important; text-decoration: none !important; }

/* §69.6 Two-up row — SCOPED to .ev-page so the Add Event form's row layout
   cannot leak onto the dashboard's own .ev-row event cards (§64). Both design
   prototypes independently named the class .ev-row; in one combined stylesheet
   the later (form) rule was overriding the dashboard's, forcing dashboard cards
   to align-items:flex-start + max-width:460px (the "fields not centred" bug). */
.ev-page .ev-row {
  display: flex;
  /* flex-direction: row — the bare `.ev-row` rule (dashboard events list, §64)
     sets flex-direction: column, which leaked here and stacked + left-aligned the
     form's two-column rows (date|time, capacity|price) at wide widths. Restate row
     so the fields sit side-by-side and centre as a group. The @container evp
     (max-width:540) query still stacks them on narrow. (Rob 29/06/26 — centring.) */
  flex-direction: row;
  align-items: flex-start;
  justify-content: center;
  gap: var(--sp-lg);
  width: 100%;
  max-width: 460px;
  margin-inline: auto;
}
.ev-page .ev-row .ev-field { flex: 1 1 0; min-width: 0; margin-top: 0; }
.ev-page .ev-row .ev-input,
.ev-page .ev-row .ev-dd { max-width: 100%; }

/* §69.7 Custom dropdown (single + multi) */
.ev-dd { position: relative; width: 100%; max-width: 460px; }
.ev-dd__btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  min-height: 44px;
  padding: 8px 38px;
  font: 600 14px var(--font-body);
  color: var(--color-navy);
  background: var(--color-surface);
  border: 2px solid var(--color-gold);
  border-radius: 10px;
  cursor: pointer;
  text-align: center;
  box-shadow: var(--shadow-gold-hover);
  transition: border-color var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out);
  margin-bottom: 0;
}
.ev-dd--open .ev-dd__btn {
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.16);
}
/* F-064 (S233, 21/09/2026). Rob on the locked Cancellation terms control: "completely off brand
   and all blue". Once an event has a booking the dropdown is replaced by a read-only line, and that
   line carried its own inline style attribute (a 1px navy-at-18% border on a navy-at-5% fill), which
   is the plain blue-grey box he photographed. There was no rule for .ev-locked-value anywhere, so
   the inline attribute WAS the source; it is removed and the control is styled here instead, beside
   the .ev-dd__btn it stands in for.
   The platform already has this idiom twice and this is the third of the same shape: the Account
   page locks Sex at birth with .form-input--readonly (the page's own input, minus the affordances)
   and the checkout locks it with .reg-dd__locked (the registration shell's own .reg-dd__btn box,
   minus its chevron room, its lift and its pointer). So the locked terms line takes the event
   form's own control geometry: the .ev-dd__btn box without the chevron padding, the shadow or the
   cursor, so it reads as a recorded value rather than as something to open. */
.ev-locked-value {
  width: 100%;
  max-width: 460px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 8px 16px;
  font: 600 14px var(--font-body);
  color: var(--color-navy);
  background: var(--color-surface);
  border: 2px solid var(--color-gold);
  border-radius: 10px;
  text-align: center;
  cursor: default;
  user-select: none;
}
/* S227 (VC cloud 01, 15/09/26). ROB: "They should be gold border at all times. Just fix the
   two on the account page first, and we'll just point out the others when we see them. Don't go
   searching for them." The navy open-state border is shared by every custom dropdown on the
   platform, so it is NARROWED to exclude the account page rather than overridden there: one
   correct rule, not a counter-rule stacked on a wrong one. body.account is carried ONLY by
   /members/<user>/account/, checked against 13 live pages. The deeper open-state shadow above
   is left applying everywhere, because he asked about the border and nothing else. */
/* S230 17/09/2026, Rob: "as soon as you click on them and the drop down menu appears, you
   should be able to move the cursor off them to one of the options without the border going
   blue. Should only ever be gold." The navy open-state border is now wrong EVERYWHERE, not
   just on the account page, so the rule is deleted rather than narrowed again: the base
   .ev-dd__btn gold border then applies in the open state too. Global, every dropdown. */
.ev-dd__value { display: inline-block; line-height: 1; }
/* S227 item 30 (Rob, create-event form): a label longer than the button painted straight over
   the gold chevron. Measured at 360 before: 261.41px of text in a 162.00px content box,
   49.70px outside the button each side, 40.70px across the chevron. After: 0.00 and 9.00px
   clear of the chevron, the button growing from 44.00px to 57.78px. 768 and up are unchanged. */
.event-submit-form .ev-dd__value { white-space: normal; line-height: 1.35; }
.ev-dd__value--ph { color: rgba(3, 27, 131, 0.65); font-style: italic; }
.ev-dd--open .ev-dd__value--ph { color: var(--color-navy); }
.ev-dd__chev {
  position: absolute;
  right: 14px;
  top: 50%;
  width: 15px;
  height: 15px;
  transform: translateY(calc(-50% - 1px));
  color: #DDB94B;
  transition: transform var(--duration-fast) var(--ease-out);
  pointer-events: none;
}
.ev-dd--open .ev-dd__chev { transform: translateY(calc(-50% - 1px)) rotate(180deg); }

.ev-dd__menu {
  position: absolute;
  z-index: 98;      /* S245 row 35: 98, was 1000 (header is 99; see 26.5.7) */
  top: calc(100% + 10px);
  left: 0; right: 0;
  max-height: 320px;
  overflow-y: auto;
  margin: 0;
  padding: 14px;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--color-surface);
  border: 2px solid var(--color-gold);
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
}
.ev-dd__menu::-webkit-scrollbar { width: 12px; }
.ev-dd__menu::-webkit-scrollbar-track { background: #ffffff; border: 1.5px solid #E0C56A; border-radius: var(--radius-pill); margin: 2px 0; }
.ev-dd__menu::-webkit-scrollbar-thumb { background: #DDB94B; border-radius: var(--radius-pill); border: 3px solid transparent; background-clip: content-box; }
.ev-dd__menu::-webkit-scrollbar-button { display: block; height: 13px; background: #ffffff no-repeat center; background-size: 9px 9px; }
.ev-dd__menu::-webkit-scrollbar-button:vertical:decrement { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23CC9900' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 15l6-6 6 6'/%3E%3C/svg%3E"); }
.ev-dd__menu::-webkit-scrollbar-button:vertical:increment { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23CC9900' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); }
.ev-dd__menu::-webkit-scrollbar-button:vertical:start:increment,
.ev-dd__menu::-webkit-scrollbar-button:vertical:end:decrement { display: none; }

.ev-dd__opt {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 14px;
  border: 1.5px solid rgba(3, 27, 131, 0.2);
  border-radius: 10px;
  background: var(--color-surface);
  font: 600 13px var(--font-body);
  color: var(--color-navy);
  text-align: center;
  cursor: pointer;
  transition: background 150ms var(--ease-out), border-color 150ms var(--ease-out);
  margin-bottom: 0;
}
.ev-dd__opt:hover { background: var(--color-cream); border-color: var(--color-gold); }
.ev-dd__opt--active { background: var(--color-cream); border-color: var(--color-gold); font-weight: 700; }
.ev-dd__tick {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  opacity: 0;
  color: var(--color-gold-dark);
}
.ev-dd__opt--active .ev-dd__tick { opacity: 1; }

.ev-dd__foot {
  margin-top: 2px;
  display: flex;
  justify-content: center;
  padding: 0;
  border: 0;
  background: transparent;
}
.ev-dd__done {
  width: 100%;
  padding: 10px 14px;
  font: 700 13px var(--font-heading);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-navy);
  background: var(--color-cream);
  border: 1.5px solid var(--color-gold);
  border-radius: 10px;
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out);
  margin-bottom: 0;
}
.ev-dd__done:hover { background: var(--color-cream-hover); }

.ev-chips {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-sm);
  max-width: 460px;
  /* Breathing room between the dropdown trigger and the selected pills.
     (T-S119-013, Rob 28/06/26.) */
  margin-top: var(--sp-sm);
}
/* `.ev-chips { display:flex }` overrides the [hidden] attribute, so when there
   are no chips re-assert display:none — otherwise the empty container's
   margin-top adds a phantom gap. */
.ev-chips[hidden] { display: none !important; }
.ev-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.02em;
  color: var(--color-navy);
  background: var(--color-cream);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-pill);
  padding: 5px 6px 5px 12px;
  line-height: 1;
}
.ev-chip__x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--color-gold-dark);
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out);
  margin-bottom: 0;
  padding: 0;
}
.ev-chip__x:hover { background: rgba(204, 153, 0, 0.18); }
.ev-chip__x svg { display: block; }

/* §69.8 Branded date field + calendar popover */
.ev-datewrap { position: relative; }
.ev-datefield {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  min-height: 46px;
  padding: 12px 42px;
  font: 400 15px var(--font-body);
  color: var(--color-navy);
  background: var(--color-surface);
  border: 2px solid var(--color-gold);
  border-radius: var(--radius-md);
  cursor: pointer;
  text-align: center;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
  transition: border-color var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out);
  margin-bottom: 0;
}
.ev-datewrap.ev-dd--open .ev-datefield {
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.16);
}
/* S227: the Date of birth half of the same change. See the note above. */
body:not(.account) .ev-datewrap.ev-dd--open .ev-datefield {
  border-color: var(--color-navy);
}
.ev-datefield__val { display: inline-block; line-height: 1; }
.ev-datefield__val--ph { color: rgba(3, 27, 131, 0.42); font-style: italic; }
.ev-datefield__icon {
  position: absolute;
  right: 14px;
  top: 50%;
  width: 17px;
  height: 17px;
  transform: translateY(calc(-50% - 1px));
  color: var(--color-gold-dark);
  pointer-events: none;
}

.ev-cal {
  position: absolute;
  z-index: 98;      /* S245 row 35: 98, was 1000 (header is 99; see 26.5.7) */
  top: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%);
  width: 268px;
  padding: var(--sp-lg) var(--sp-md) var(--sp-md);
  background: var(--color-surface);
  border: 2px solid var(--color-gold);
  border-radius: var(--radius-md);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
}
.ev-cal__hd {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-sm);
  margin-bottom: var(--sp-md);
}
.ev-cal__mo {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 14px;
  color: var(--color-navy);
  letter-spacing: 0.01em;
}
.ev-cal__nav {
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  background: transparent;
  border: 1.5px solid var(--color-gold);
  border-radius: 8px;
  font-size: 16px;
  line-height: 1;
  color: var(--color-navy);
  cursor: pointer;
  padding: 0;
  transition: background var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out);
  margin-bottom: 0;
}
/* Seeko's `button:hover` strips border-color to transparent, so restate the
   gold border (+ cream bg, navy text) on hover. (T-S119-014, Rob 28/06/26.) */
.ev-cal__nav:hover {
  background: var(--color-cream) !important;
  border-color: var(--color-gold) !important;
  color: var(--color-navy) !important;
}
.ev-cal__wd {
  display: grid;
  grid-template-columns: repeat(7, 32px);
  justify-content: center;
  gap: 2px;
  margin-bottom: 6px;
}
.ev-cal__wd-cell {
  display: grid;
  place-items: center;
  height: 18px;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.ev-cal__grid {
  display: grid;
  grid-template-columns: repeat(7, 32px);
  justify-content: center;
  gap: 2px;
}
.ev-cal__cell {
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  /* S227 (Rob, S225: the selected day's circle sits low). place-items:center centres the
     digit's LINE BOX, and a digit paints only cap height, which sits high inside it, so the
     ink measured 1.125px ABOVE the circle's centre at dpr 1, 2, 3, 4 and 8 alike. 2px of
     padding at the top shrinks the content box from above, so the digit drops exactly
     1.000px while the circle, which is the border box, does not move. Measured after:
     0.125px at dpr 8. Replaces `padding: 0` below; it is not stacked on it. */
  transform: translateY(3px);
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 12px;
  color: var(--color-navy);
  background: transparent;
  border: 1.5px solid transparent;
  border-radius: 50%;
  cursor: pointer;
  /* S229 16/09/26 (T-S229-011): reverted to 0 on Rob's word, "the before is correct and the
     after is wrong". The S227 2px top padding dropped the digit 1.000px inside the ring. */
  padding: 0;
  margin-bottom: 0;
  transition: background var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out);
}
.ev-cal__cell--blank { visibility: hidden; pointer-events: none; cursor: default; }
/* Hover (cursor moving over the numbers) highlights with the design's success
   greens — the same greens the toggles use. Applies to every cell incl. today.
   (Rob 29/06/26.)
   S245 S9-61 (off-token greens): the fallbacks after the commas in this section and in the toggle rules below were #2E7D4F and #E6F5EC, in no brand
   guide (S238 X06b ruled the same for the password line). They never painted, because --color-success and --color-success-bg are always set
   (design-tokens.css 1.5), but a hex audit reads them as off-token greens; they now hold the tokens' own values, #27A644 and rgba(39, 166, 68, 0.08). */
.ev-cal__cell:hover:not(.ev-cal__cell--sel) {
  background: var(--color-success-bg, rgba(39, 166, 68, 0.08)) !important;
  border-color: var(--color-success, #27A644) !important;
  color: var(--color-success, #27A644) !important;
}
/* Today = cream + gold (so it's distinguishable at rest). Mirrors the Dashboard
   mini-calendar. (T-S119-015.) */
.ev-cal__cell--today {
  background: var(--color-cream) !important;
  border-color: var(--color-gold) !important;
  color: var(--color-navy) !important;
}
/* Selected date = green, and it STAYS green (beats today). Dark-green border +
   text, light-green background — same success greens as the toggles. (Rob 29/06/26.) */
.ev-cal__cell--sel,
.ev-cal__cell--today.ev-cal__cell--sel {
  background: var(--color-success-bg, rgba(39, 166, 68, 0.08)) !important;
  border-color: var(--color-success, #27A644) !important;
  color: var(--color-success, #27A644) !important;
  font-weight: 700;
}
.ev-cal__foot { margin-top: var(--sp-md); }
.ev-cal__clear {
  width: 100%;
  padding: 9px 14px;
  font: 700 12px var(--font-heading);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-navy);
  background: var(--color-cream);
  border: 1.5px solid var(--color-gold);
  border-radius: 10px;
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out);
  margin-bottom: 0;
}
.ev-cal__clear:hover {
  background: var(--color-cream-hover) !important;
  border-color: var(--color-gold) !important;
  color: var(--color-navy) !important;
}

/* §69.x Brand-hover overrides for the dropdown + date/time field buttons.
   Without these, Seeko's `button:hover { background:#f0f0f0; color:#191919;
   border-color:transparent }` paints an off-brand grey overlay on hover and
   strips the gold border. Per Rob 28/06/26. */
.ev-dd__btn:hover,
.ev-datefield:hover {
  background: var(--color-cream) !important;
  border-color: var(--color-gold) !important;
  color: var(--color-navy) !important;
}
/* Pressed and in-flight (D-640): darker cream, no shadow. R3-08 25/09/26: the parent theme's
   button:not([disabled]):not(.disabled):active reset (0,3,1) paints grey/transparent, and its
   separate button:focus reset adds a flat rgba(0,0,0,0.5) 0 0 0 0 shadow on the real click-focus
   that goes with a hold; this button had no :active rule of its own so both won. Placed after
   :hover so equal-specificity source order gives this the win while both match during a real
   hold (mirrors the .week-nav__btn:active idiom above in this file). */
.ev-dd__btn:active {
  background: var(--color-cream-hover) !important;
  box-shadow: none !important;
}

/* §69.9 Branded time picker popover */
.ev-timepop {
  position: absolute;
  z-index: 98;      /* S245 row 35: 98, was 1000 (header is 99; see 26.5.7) */
  top: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%);
  width: 204px;
  padding: 12px;
  background: var(--color-surface);
  border: 2px solid var(--color-gold);
  border-radius: var(--radius-md);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
}
.ev-timepop__cols { display: flex; align-items: stretch; justify-content: center; gap: 6px; }
.ev-timepop__sep {
  display: flex;
  align-items: center;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 18px;
  color: var(--color-navy);
}
.ev-scroller { display: flex; flex: 1; min-width: 0; gap: 5px; }
.ev-timecol {
  flex: 1;
  min-width: 0;
  max-height: 184px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 6px;
  position: relative;
  border: 1.5px solid var(--color-gold);
  border-radius: 12px;
  scrollbar-width: none;
}
.ev-timecol::-webkit-scrollbar { display: none; }
.ev-scroller__bar { width: 16px; flex: none; display: flex; flex-direction: column; align-items: center; }
.ev-scroller__btn {
  flex: none; width: 16px; height: 14px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  background: none; border: none; cursor: pointer; color: var(--color-gold);
  transition: color var(--duration-fast) var(--ease-out);
  margin-bottom: 0;
}
.ev-scroller__btn:hover { color: #b88600; }
.ev-scroller__track {
  flex: 1; width: 12px; margin: 3px 0;
  background: #ffffff;
  border: 1.5px solid #E0C56A;
  border-radius: var(--radius-pill);
  position: relative;
}
.ev-scroller__thumb {
  position: absolute; left: 1px; right: 1px;
  min-height: 22px;
  background: #DDB94B;
  border-radius: var(--radius-pill);
  cursor: grab;
  touch-action: none;
}
.ev-scroller__thumb:active { cursor: grabbing; }
.ev-timecol__opt {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px 0;
  border: 1.5px solid rgba(3, 27, 131, 0.18);
  border-radius: 8px;
  background: var(--color-surface);
  font: 700 13px var(--font-heading);
  color: var(--color-navy);
  cursor: pointer;
  transition: background 150ms var(--ease-out), border-color 150ms var(--ease-out);
  margin-bottom: 0;
}
.ev-timecol__opt:hover { background: var(--color-cream); border-color: var(--color-gold); }
.ev-timecol__opt--sel { background: var(--color-cream); border-color: var(--color-gold); color: var(--color-navy); font-weight: 700; }
.ev-timepop__foot { margin-top: 10px; }

/* §69.10 Toggle (D019 custom) */
.ev-toggle {
  /* `flex` + `width:100%` (not `inline-flex`) so the toggle expands to fill
     its parent up to max-width:480px. With inline-flex the toggle was
     shrink-to-content, which meant the body had no parent width to wrap
     within and its long subtext overflowed the toggle's gold border. */
  display: flex;
  width: 100%;
  align-items: center;
  /* Track on the left, body on the right — explicit so an inherited
     justify-content:center doesn't centre the overflowing content group and
     push the knob outside the toggle's left border at narrow widths. */
  justify-content: flex-start !important;
  gap: var(--sp-md);
  max-width: 480px;
  box-sizing: border-box;
  padding: 14px 18px;
  /* Cream rest background (not white) per Rob 29/06/26; flips to brand green when ON. */
  background: var(--color-cream);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  cursor: pointer;
  text-align: left;
  box-shadow: 0 2px 8px rgba(3, 27, 131, 0.06);
  transition: background var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out);
  margin-bottom: 0;
}
/* Brand hover — cream bg + gold border. surface-raised was reading as grey
   and Seeko's `button:hover` strips border-color, so restate it. Per Rob 28/06/26. */
/* No background change on hover — stays light cream until toggled ON (then green).
   cream-hover wasn't a design token pairing. (Rob 29/06/26.) */
.ev-toggle:not(.ev-toggle--on):hover {
  background: var(--color-cream) !important;
  border-color: var(--color-gold) !important;
}
.ev-toggle__track {
  position: relative;
  flex-shrink: 0;
  width: 46px;
  height: 26px;
  border-radius: var(--radius-pill);
  background: var(--color-surface);
  border: 2px solid var(--color-gold);
  transition: background var(--duration-fast) var(--ease-out);
}
.ev-toggle__knob {
  position: absolute;
  top: 50%;
  left: 3px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--color-navy);
  transform: translateY(-50%);
  transition: left var(--duration-fast) var(--ease-out), background var(--duration-fast) var(--ease-out);
}
.ev-toggle--on { background: var(--color-success-bg, rgba(39, 166, 68, 0.08)); border-color: var(--color-success, #27A644); }
.ev-toggle--on .ev-toggle__track { background: var(--color-success, #27A644); border-color: var(--color-success, #27A644); }
.ev-toggle--on .ev-toggle__knob { left: 23px; background: var(--color-surface); }
.ev-toggle--on .ev-toggle__label,
.ev-toggle--on .ev-toggle__sub { color: var(--color-success, #27A644); }
/* Once ON, keep the brand-green surface on hover/active too. Seeko's
   `button:hover { background:#f0f0f0 }` was stomping the green back to grey
   the moment the cursor sat on the just-clicked toggle, which read as "stays
   grey after click". Restate every property Seeko touches. (T-S119-017.) */
.ev-toggle--on:hover,
.ev-toggle--on:active,
.ev-toggle--on:focus {
  background: var(--color-success-bg, rgba(39, 166, 68, 0.08)) !important;
  border-color: var(--color-success, #27A644) !important;
}
.ev-toggle--on:hover .ev-toggle__track,
.ev-toggle--on:active .ev-toggle__track {
  background: var(--color-success, #27A644) !important;
  border-color: var(--color-success, #27A644) !important;
}
.ev-toggle--on:hover .ev-toggle__label,
.ev-toggle--on:hover .ev-toggle__sub {
  color: var(--color-success, #27A644) !important;
}
/* `flex: 1 1 auto; min-width: 0` so the body fills the toggle minus the track
   + gap, and can shrink so text wraps inside the toggle's border at narrow
   widths. `align-items: stretch` so the label + sub children fill body's
   width and wrap; `text-align: center` keeps the actual text visually centred. */
/* white-space: normal — the toggle is a <button>, which inherits white-space:
   nowrap from the theme, so the subtext refused to wrap and overflowed the right
   border. Force normal wrapping. (T-S119-012 real cause, Rob 29/06/26.) */
.ev-toggle__body,
.ev-toggle__label,
.ev-toggle__sub { white-space: normal; }
.ev-toggle__body { display: flex; flex-direction: column; align-items: stretch; gap: 3px; text-align: center; flex: 1 1 auto; min-width: 0; }
.ev-toggle__label {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 13px;
  color: var(--color-navy);
  line-height: 1.3;
}
.ev-toggle__sub {
  font-size: 12px;
  color: var(--color-text-secondary);
  line-height: 1.4;
}

/* §69.11 File picker */
.ev-file { width: 100%; max-width: 460px; position: relative; }
.ev-file__input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.ev-file__row {
  display: flex;
  align-items: stretch;
  width: 100%;
  border: 2px dashed var(--color-gold);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-surface);
  cursor: pointer;
}
.ev-file__btn {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 18px;
  font: 700 13px var(--font-heading);
  letter-spacing: 0.03em;
  color: var(--color-navy);
  background: var(--color-cream);
  border-right: 2px dashed var(--color-gold);
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out);
}
.ev-file__btn:hover { background: var(--color-cream-hover); }
.ev-file__name {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 12px 14px;
  font: 600 13px var(--font-body);
  color: var(--color-text-muted);
  text-align: center;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ev-file__name--set { color: var(--color-navy); font-style: normal; }

/* §69.12 Banner colour swatches */
.ev-swatches {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-md);
}
.ev-swatch {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 2px solid var(--color-surface);
  box-shadow: 0 0 0 1.5px rgba(3, 27, 131, 0.18), 0 2px 6px rgba(3, 27, 131, 0.16);
  cursor: pointer;
  padding: 0;
  transition: transform var(--duration-fast) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out);
  margin-bottom: 0;
}
.ev-swatch:hover { transform: scale(1.1); }
.ev-swatch--active {
  box-shadow: 0 0 0 3px var(--color-gold), 0 2px 8px rgba(204, 153, 0, 0.3);
  transform: scale(1.06);
}

/* §69.13 Submit */
.ev-submit {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-md);
  margin-top: var(--sp-2xl);
}
.ev-submit .btn--primary {
  min-width: 260px;
  font-size: 15px;
  padding: 14px 32px;
}
/* Seeko's `button:hover` strips border-color to transparent and shifts text to
   grey. Restate the gold border + navy text on hover so the Update/Publish
   button keeps its ring + readable colour. Per Rob 28/06/26. */
.ev-submit .btn--primary:hover,
.ev-submit .btn--primary:focus {
  border-color: var(--color-gold) !important;
  color: var(--color-navy) !important;
  background: var(--color-cream-hover, var(--color-cream)) !important;
}
.ev-submit__note {
  font-size: 13px;
  color: var(--color-text-secondary);
  text-align: center;
  max-width: 420px;
  line-height: 1.5;
}

/* §69.14 Responsive */
@container evp (max-width: 540px) {
  .ev-page .ev-row { flex-direction: column; align-items: center; gap: var(--sp-xl); }
  .ev-page .ev-row .ev-field { width: 100%; }
  .ev-page .ev-row .ev-field + .ev-field { margin-top: 0; }
  .ev-head__title { font-size: 24px; }
  .ev-card { padding: var(--sp-xl) var(--sp-lg); }
}

/* ── §69.x SCOPE-BUMPS — defeat Seeko / BuddyPress / inline-footer rules ──── */

/* §69.20 Seeko's input + textarea base rules will fight our .ev-input border /
   padding / color. Scope-bump everything the theme touches. S238 STYLE: the
   organiser's decline reason field in the Refund requests panel (F40e, on the
   event page, outside .ev-page) is the same field and takes the same scope. */
.ev-page .ev-input,
.ev-page .ev-textarea,
.event-refund-req .ev-textarea,
#buddypress .ev-page .ev-input,
#buddypress .ev-page .ev-textarea {
  border: 2px solid var(--color-gold) !important;
  background: var(--color-surface) !important;
  color: var(--color-navy) !important;
  border-radius: var(--radius-md) !important;
  box-sizing: border-box !important;
}
html[data-nav="kbd"] .ev-page .ev-input:focus,
html[data-nav="kbd"] .ev-page .ev-textarea:focus,
html[data-nav="kbd"] .event-refund-req .ev-textarea:focus,
html[data-nav="kbd"] #buddypress .ev-page .ev-input:focus,
html[data-nav="kbd"] #buddypress .ev-page .ev-textarea:focus {
  box-shadow: 0 0 0 2px rgba(204, 153, 0, 0.25) !important;
  border-color: var(--color-gold) !important;
}

/* §69.21 All buttons inside the form get neutralised against Seeko's `button {
   margin-bottom: 1rem; background-color: #fff; color: navy; padding: …; border: …;
   font-size: …; line-height: … }` and `button:hover { background-color: #f0f0f0;
   color: #191919; border-color: transparent }`. Each .ev- button class sets its
   own visuals; we just defeat the theme's margin-bottom + hover-color stomp. */
.ev-page button[type="button"],
#buddypress .ev-page button[type="button"] {
  margin-bottom: 0 !important;
}
/* Card title + step pill is a span, not a button — these survive on their own. */

/* §69.22 The branded submit button uses the canonical .btn .btn--primary which
   already has scope-bumps elsewhere. Width override sits inside .ev-submit so no
   extra bumps needed. */

/* end of §69 */

/* §70 ==========================================================================
   REGISTRATION + MEMBERSHIP CONFIRMATION — design-agent port (S136, 19/07/26)
   Source: design_handoff_registration/design/{checkout.css,confirmation.css}
           design_handoff_membership_confirmation/design/confirmation.css
           + the shared design-system rules from design/styles.css that these
           two pages use.
   Governed by D-267 (these two pages become the ONLY versions) and D-149 /
   CLAUDE.md Rule 4: the design's rule BODIES are copied byte-for-byte. Where a
   theme/plugin rule fights them, the fix is a specificity scope-bump on the
   DESIGN's selector — never an edit to the design's values.

   SCOPING NOTE (deliberate, not a deviation): these are STANDALONE pages, not
   dashboard workspace content, so the shared design-system rules (.card, .btn,
   .form-*, .tier-badge, .invoice-status) are ported scoped under .uks-page-shell.
   Copying them unscoped would redefine classes that other, already-signed-off
   pages rely on. The rule bodies are verbatim; only the selector is prefixed,
   which is exactly the sanctioned scope-bump.
   ============================================================================ */

/* §70.0 Page shell + container-query root. The design's @container vp queries
   need a NAMED container on an ANCESTOR of .confirm-shell (an element cannot
   query itself), so the wrapper carries it. */
.uks-page-shell {
  container-type: inline-size;
  container-name: vp;
  width: 100%;
}

/* §70.1 Shared design-system tokens + components, verbatim from design/styles.css,
   scoped to the two ported pages. */
.uks-page-shell {
  --color-navy: #031B83;
  --color-navy-light: #0A2DAA;
  --color-gold: #CC9900;
  --color-gold-dark: #80641D;
  --color-gold-light: #FFD700;
  --color-cream: #FFFBE6;
  --color-cream-hover: #FFF5CC;
  --color-bg: #F8F8F8;
  --color-surface: #FFFFFF;
  --color-surface-raised: #F8F7F4;
  --color-surface-sunken: #F3F2EF;
  --color-text: #1A1A2E;
  --color-text-secondary: rgba(3, 27, 131, 0.75);
  --color-text-muted: rgba(3, 27, 131, 0.65);  /* S229 (T-S215-009 d), Rob: navy at 55 per cent reads grey; 65 reads blue. */
  --color-success: #27A644;
  --color-success-bg: rgba(39, 166, 68, 0.08);
  --color-error: #C41C1C;
  --color-warning: #D97706;
  --color-warning-bg: rgba(217, 119, 6, 0.08);
  --sp-xs: 4px; --sp-sm: 8px; --sp-md: 12px; --sp-lg: 16px;
  --sp-xl: 24px; --sp-2xl: 32px; --sp-3xl: 48px; --sp-4xl: 64px;
  --radius-sm: 4px; --radius-md: 16px; --radius-lg: 16px; --radius-pill: 9999px;
  --shadow-sm: 0 1px 2px rgba(26, 26, 46, 0.04), 0 2px 4px rgba(26, 26, 46, 0.04);
  --shadow-gold-hover: 0 4px 12px rgba(0, 0, 0, 0.16);
  --font-heading: 'Montserrat', system-ui, sans-serif;
  --font-body: 'Nunito Sans', system-ui, sans-serif;
  --duration-fast: 150ms; --duration-normal: 250ms; --duration-slow: 400ms;
  --ease-out: cubic-bezier(0.25, 1, 0.5, 1);
}

.uks-page-shell .card {
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: var(--sp-xl);
  box-shadow: var(--shadow-sm);
}
.uks-page-shell .card + .card { margin-top: var(--sp-lg); }

.uks-page-shell .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-sm);
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 14px;
  line-height: 1;
  padding: 10.5px 24px;
  border-radius: 10px;
  border: 2px solid transparent;
  cursor: pointer;
  transition: all var(--duration-fast) var(--ease-out);
  white-space: nowrap;
  text-decoration: none;
  margin-bottom: 0;
  min-height: 0;
  width: auto;
}
.uks-page-shell .btn:hover { text-decoration: none; }
.uks-page-shell .btn--primary {
  background: var(--color-cream);
  border-color: var(--color-gold);
  color: var(--color-navy);
  box-shadow: 0 2px 6px rgba(3,27,131,.08), 0 3px 10px rgba(204,153,0,.16);
}
.uks-page-shell .btn--primary:hover {
  background: var(--color-cream-hover);
  border-color: var(--color-gold);
  color: var(--color-navy);
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(3,27,131,.10), 0 8px 24px rgba(204,153,0,.28);
}
.uks-page-shell .btn--primary:active {
  background: var(--color-cream);
  border-color: var(--color-gold);
  color: var(--color-navy);
  transform: translateY(0);
  box-shadow: none;
  transition-duration: 60ms;
}
.uks-page-shell .btn--subtle {
  background: transparent;
  border: 0;
  color: var(--color-navy);
  padding: 6px 8px;
  font-weight: 600;
  font-size: 13px;
  border-radius: 8px;
}
.uks-page-shell .btn--subtle:hover {
  background: var(--color-surface-raised);
  color: var(--color-navy);
  border-color: transparent;
  text-decoration: none;
}
.uks-page-shell .btn--sm { padding: 8px 16px; font-size: 13px; }

.uks-page-shell .form-row {
  display: flex; flex-direction: column; gap: 6px;
  align-items: center; text-align: center;
}
.uks-page-shell .form-label {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 13px;
  color: var(--color-navy);
  letter-spacing: 0.01em;
  align-self: center;
  margin: 0;
  display: block;
}
.uks-page-shell .form-hint { font-size: 12px; color: var(--color-text-secondary); }
.uks-page-shell .form-input,
.uks-page-shell .form-select,
.uks-page-shell .form-textarea {
  width: 100%;
  padding: 11px 14px;
  font: 400 14px var(--font-body);
  color: var(--color-navy);
  background: var(--color-surface);
  border: 2px solid var(--color-gold);
  border-radius: var(--radius-md);
  outline: none;
  text-align: center;
  transition: box-shadow var(--duration-fast) var(--ease-out);
  margin-bottom: 0;
  box-shadow: none;
  height: auto;
  max-width: none;
}
.uks-page-shell .form-input::placeholder,
.uks-page-shell .form-textarea::placeholder { color: rgba(3, 27, 131, 0.65); text-align: center; }
html[data-nav="kbd"] .uks-page-shell .form-input:focus,
html[data-nav="kbd"] .uks-page-shell .form-select:focus {
  box-shadow: 0 0 0 2px rgba(204, 153, 0, 0.25) !important;
  border-color: var(--color-gold);
  outline: none;
}
/* S245 row 21 (Rob, the 6th of October 2026: "When you click into one of these input fields the border changes colour. It should not change. All of the fields, not just the one pictured (Confirm Password)."):
   the design above gives a focus change to a keyboard user only (html[data-nav="kbd"]) and none to a click, so the border stays the field's own 2px gold. What turned it blue was not the design: PMPro's own
   `.pmpro_form_input-password:focus` (and the text and e-mail twins, paid-memberships-pro variation_1.css 366, border-color #80bdff, specificity 0,3,0, loaded after this file) and Seeko's
   `input[type="password"]:focus` (seeko-dynamic.css, rgba(204, 153, 0, 0.6)). Measured live at 1280 with the field focused: Username, Password, Confirm Password, E-mail Address, Confirm E-mail Address and the discount code
   all went rgb(204, 153, 0) to rgb(128, 189, 255); Postcode did not (an inline rule pins it). Same as the design's own border colour, stated for the focused field at 0,3,1 so it outranks both third-party rules
   without !important; the keyboard rule above (0,3,0 plus html[data-nav], with its ring) still applies on top of it. The discount code input carries .pmpro_form_input and not .form-input, so it is named too. */
.uks-page-shell input.form-input:focus,
.uks-page-shell input.pmpro_form_input:focus { border-color: var(--color-gold); }
.uks-page-shell .form-input:disabled {
  background: var(--color-surface-sunken); color: var(--color-text-muted); cursor: not-allowed;
}
/* S245 row 30 (Rob, the 6th of October 2026: "I do not know why these fields have blue backgrounds once you type something in. That is wrong."): the pale blue is the browser's own autofill tint on a field it
   filled (Chrome paints :-webkit-autofill with background-color #E8F0FE !important, rgb(232, 240, 254); measured live at 1280 with the autofill state forced on Username: rgb(232, 240, 254)). It cannot be overridden
   with a background, so the same override the events search takes at 28.10.5 (S77, Rob: "force white bg on autofill ... Seeko and some browser extensions tint inputs light-blue-grey") paints the field's own white over it
   with an inset shadow, for every state the field can be in. The typed value stays the navy section 0 gives autofilled text. Scoped to the registration shell so no other page changes. */
.uks-page-shell input:-webkit-autofill,
.uks-page-shell input:-webkit-autofill:hover,
.uks-page-shell input:-webkit-autofill:focus,
.uks-page-shell input:-webkit-autofill:active {
  -webkit-box-shadow: 0 0 0 1000px #ffffff inset !important;
  -webkit-text-fill-color: #031B83 !important;
}

.uks-page-shell .tier-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 4px 12px 5px;
  border-radius: var(--radius-pill);
}
.uks-page-shell .tier-badge--free { color: var(--color-navy); background: var(--color-cream); border: 1px solid var(--color-gold); }  /* R3-06 24/09/2026: overrides BRAND_GUIDE 11's grey, Rob never agreed to grey anywhere - see 42.7 */
.uks-page-shell .tier-badge--standard { color: var(--color-navy); background: var(--color-cream); border: 1px solid var(--color-gold); }  /* D-652 25/09/2026: all tier pills cream and gold - see 42.7 */
.uks-page-shell .tier-badge--premium { color: var(--color-navy); background: var(--color-cream); border: 1px solid var(--color-gold); }  /* D-652 25/09/2026: all tier pills cream and gold - see 42.7 */
.uks-page-shell .tier-badge--venue { color: var(--color-navy); background: var(--color-cream); border: 1px solid var(--color-gold); }  /* D-652 25/09/2026: all tier pills cream and gold - see 42.7 */
.uks-page-shell .tier-badge--organiser { color: var(--color-navy); background: var(--color-cream); border: 1px solid var(--color-gold); }  /* D-652 25/09/2026: all tier pills cream and gold - see 42.7 */
.uks-page-shell .tier-badge--dating { color: var(--color-navy); background: var(--color-cream); border: 1px solid var(--color-gold); }  /* D-652 25/09/2026: was missing entirely (Rule 13) - see 42.7 */

.uks-page-shell .invoice-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 3px 10px 4px;
  border-radius: var(--radius-pill);
}
.uks-page-shell .invoice-status--paid { color: var(--color-success); background: var(--color-success-bg); }

/* ---- §70.2 confirmation.css — VERBATIM from confirmation.css, selectors scope-bumped only ---- */
.uks-page-shell .confirm-shell {
  background: var(--color-bg);
  padding: var(--sp-4xl) var(--sp-xl);
  min-height: 60vh;
}
.uks-page-shell .confirm-shell__header {
  text-align: center;
  margin-bottom: var(--sp-2xl);
}
.uks-page-shell .confirm-shell__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 40px;
  color: var(--color-navy);
  letter-spacing: -0.02em;
  margin: 0 0 var(--sp-sm);
}
.uks-page-shell .confirm-shell__subtitle {
  font-size: 17px;
  color: var(--color-gold-dark);
  margin: 0;
}
/* S182 (Rob, watching the VS4 checkout legs live): on the REGISTRATION page the subtitle reads
   navy ("the 'nearly there' text should be blue") and the refusal banner's text is centred.
   Scoped to .uks-registration so the confirmation page's own subtitle stays as designed. */
.uks-registration .confirm-shell__subtitle { color: var(--color-navy) !important; }
.uks-registration .pmpro_message,
.uks-registration #pmpro_message { text-align: center !important; }
.uks-page-shell .confirm-page {
  max-width: 860px;
  margin-inline: auto;
}
@container vp (max-width: 599px) {
  .uks-page-shell .confirm-shell { padding: var(--sp-2xl) var(--sp-lg);
  }
  .uks-page-shell .confirm-shell__title { font-size: 28px;
  }
}
.uks-page-shell .confirm-hero {
  background: #fff;
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: 34px var(--sp-2xl);
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--sp-lg);
  position: relative;
  overflow: hidden;
  margin-bottom: var(--sp-xl);
}
.uks-page-shell .confirm-hero > * { position: relative; z-index: 1;
}
.uks-page-shell .confirm-check {
  width: 76px;
  height: 76px;
  border-radius: 50%;
  background: #fff;
  color: var(--color-success);
  display: grid;
  place-items: center;
  border: 1.5px solid var(--color-gold);
}
.uks-page-shell .confirm-check__emoji {
  font-size: 40px;
  line-height: 1;
  display: block;
  /* Optically centre the 🎉 ink (it leans low-left in its em box). */
  transform: translate(2px, -1px);
}
.uks-page-shell .confirm-hero__badge-row {
  display: flex;
  align-items: center;
  gap: var(--sp-sm);
}
.uks-page-shell .confirm-hero .tier-badge {
  border: 1.5px solid var(--color-gold);
  padding: 5px 12px 4px;
  background: var(--color-cream);
  color: var(--color-navy);
}
.uks-page-shell .confirm-hero__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 26px;
  line-height: 1.2;
  color: var(--color-navy);
  letter-spacing: -0.01em;
  margin: 0;
}
.uks-page-shell .confirm-hero__body {
  max-width: 580px;
  font-size: 15.5px;
  line-height: 1.6;
  color: var(--color-text-secondary);
  text-wrap: pretty;
  margin: 0;
}
.uks-page-shell .confirm-hero__body strong { color: var(--color-gold); font-weight: 700;
}
.uks-page-shell .receipt__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--sp-md);
  padding-bottom: var(--sp-lg);
  border-bottom: 1px solid var(--color-gold-light);
  margin-bottom: var(--sp-xl);
}
.uks-page-shell .receipt__head-title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 20px;
  color: var(--color-gold);
  margin: 0;
  letter-spacing: -0.01em;
}
.uks-page-shell .receipt__head-sub {
  font-size: 13px;
  color: var(--color-text-muted);
}
.uks-page-shell .receipt__head-meta {
  display: flex;
  align-items: center;
  gap: var(--sp-sm);
  flex-wrap: wrap;
  margin-top: 9px;
}
.uks-page-shell .receipt__head-meta .invoice-status--paid { border: 1.5px solid #27A644;   /* S213 greens: was #1E7E34, an off-token dark green. */ padding: 4px 10px 3px;
}
.uks-page-shell .confirm-hero .invoice-status--paid { border: 1.5px solid #27A644;   /* S213 greens: was #1E7E34, an off-token dark green. */ padding: 4px 10px 3px;
}
.uks-page-shell .receipt__head .btn--subtle { color: var(--color-error);
}
.uks-page-shell .receipt__head .btn--subtle svg { color: var(--color-error);
}
.uks-page-shell .receipt__rows {
  display: flex;
  flex-direction: column;
  gap: var(--sp-md);
}
.uks-page-shell .receipt__row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  font-size: 15px;
  min-height: 26px;
}
.uks-page-shell .receipt__row-label {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-gold-dark);
  text-align: right;
  padding-right: var(--sp-lg);
}
.uks-page-shell .receipt__row-value {
  color: var(--color-navy);
  padding-left: var(--sp-lg);
  border-left: 1.5px solid var(--color-gold-light);
}
.uks-page-shell .receipt__row-value strong { color: var(--color-navy); font-weight: 700;
}
.uks-page-shell .receipt__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0;
  margin-top: var(--sp-xl);
  padding-top: var(--sp-xl);
  border-top: 1px solid var(--color-gold-light);
}
.uks-page-shell .receipt__grid > div {
  padding-inline: var(--sp-2xl);
  border-left: 1.5px solid var(--color-gold-light);
  text-align: center;
}
.uks-page-shell .receipt__grid > div:first-child { padding-left: 0; border-left: 0;
}
.uks-page-shell .receipt__grid > div:last-child { padding-right: 0;
}
.uks-page-shell .receipt__col-label {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-gold-dark);
  margin-bottom: var(--sp-sm);
}
.uks-page-shell .receipt__col-value {
  font-size: 15px;
  line-height: 1.6;
  color: var(--color-navy);
}
.uks-page-shell .receipt__col-value .muted { color: var(--color-text-muted); font-size: 13px;
}
.uks-page-shell .receipt__total {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 30px;
  color: var(--color-navy);
  line-height: 1;
}
.uks-page-shell .receipt__total-note {
  display: block;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 12px;
  color: var(--color-success);
  margin-top: var(--sp-xs);
}
.uks-page-shell .receipt__foot {
  display: flex;
  justify-content: center;
  margin-top: var(--sp-xl);
  padding-top: var(--sp-lg);
  border-top: 1px solid var(--color-gold-light);
}
.uks-page-shell .receipt__foot .btn--primary { padding: 10px 24px 11px;
}
@container vp (max-width: 767px) {
  .uks-page-shell .receipt__row { grid-template-columns: 1fr; row-gap: 3px; text-align: center; min-height: 0;
  }
  .uks-page-shell .receipt__row-label { padding-right: 0; text-align: center;
  }
  .uks-page-shell .receipt__row-value { padding-left: 0; border-left: 0; text-align: center;
  }
  .uks-page-shell .receipt__head { flex-direction: column-reverse; align-items: center; justify-content: center; text-align: center; gap: var(--sp-md);
  }
  .uks-page-shell .receipt__foot { justify-content: center;
  }
  .uks-page-shell .receipt__foot .btn { width: auto; min-width: 240px;
  }
}
@container vp (min-width: 481px) and (max-width: 767px) {
  .uks-page-shell .receipt__rows { display: grid; grid-template-columns: 1fr 1fr; gap: 0;
  }
  .uks-page-shell .receipt__rows .receipt__row {
    padding: var(--sp-md) var(--sp-lg);
    border-left: 1.5px solid var(--color-gold-light);
  }
  .uks-page-shell .receipt__rows .receipt__row:nth-child(2n+1) { border-left: 0; padding-left: 0;
  }
  .uks-page-shell .receipt__rows .receipt__row:nth-child(2n) { padding-right: 0;
  }
  .uks-page-shell .receipt__rows .receipt__row:nth-child(n+3) { border-top: 1.5px solid var(--color-gold-light);
  }
  .uks-page-shell .receipt__grid { grid-template-columns: 1fr 1fr; gap: 0;
  }
  .uks-page-shell .receipt__grid > div { padding-inline: var(--sp-lg); border-left: 1.5px solid var(--color-gold-light);
  }
  .uks-page-shell .receipt__grid > div:nth-child(1) { padding-left: 0; border-left: 0;
  }
  .uks-page-shell .receipt__grid > div:nth-child(2) { padding-right: 0;
  }
  .uks-page-shell .receipt__grid > div:nth-child(3) {
    grid-column: 1 / -1;
    padding-inline: 0;
    border-left: 0;
    margin-top: var(--sp-lg);
    padding-top: var(--sp-lg);
    border-top: 1.5px solid var(--color-gold-light);
  }
  .uks-page-shell .receipt__foot { margin-top: var(--sp-lg);
  }
}
@container vp (max-width: 480px) {
  .uks-page-shell .receipt__grid { grid-template-columns: 1fr; gap: 0;
  }
  .uks-page-shell .receipt__grid > div { padding-inline: 0; border-left: 0;
  }
  .uks-page-shell .receipt__grid > div + div {
    margin-top: var(--sp-lg);
    padding-top: var(--sp-lg);
    border-top: 1.5px solid var(--color-gold-light);
  }
  .uks-page-shell .receipt__rows .receipt__row + .receipt__row {
    margin-top: var(--sp-md);
    padding-top: var(--sp-md);
    border-top: 1.5px solid var(--color-gold-light);
  }
  .uks-page-shell .receipt__foot { margin-top: var(--sp-lg);
  }
}

/* ---- §70.3 checkout.css — VERBATIM from checkout.css, selectors scope-bumped only ---- */
.uks-page-shell .checkout-page { max-width: 760px; margin-inline: auto;
}
.uks-page-shell .checkout-page .card + .card { margin-top: var(--sp-xl);
}
.uks-page-shell .level-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
.uks-page-shell .level-card__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 22px;
  color: var(--color-navy);
  letter-spacing: -0.01em;
  margin: 0 0 var(--sp-lg);
}
.uks-page-shell .level-card__body {
  text-align: center;
  font-size: 16px;
  line-height: 1.7;
  color: var(--color-navy);
  margin: 0;
  text-wrap: pretty;
}
.uks-page-shell .level-card__body strong { color: var(--color-gold); font-weight: 700;
}
.uks-page-shell .level-card__change {
  margin: var(--sp-md) 0 var(--sp-lg);
  align-self: center;
  border-radius: 999px;
  padding-top: 6px;
  padding-bottom: 10px;
}
.uks-page-shell .level-card__price { margin-top: 0;
}
.uks-page-shell .checkout-section-title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 22px;
  color: var(--color-navy);
  text-align: center;
  letter-spacing: -0.01em;
  margin: 0 0 var(--sp-xl);
}
.uks-page-shell .field-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-xl) var(--sp-lg);
}
.uks-page-shell .field-grid .form-row--half { grid-column: span 1;
}
/* S159: the Organiser and Venue application fieldsets are DIRECT CHILDREN of this grid, so
   without this they became grid ITEMS and rendered inside a single 225px column, with two
   thirds of the card empty and "Organiser Details" wrapping onto two lines. They are whole
   nested cards, not form rows, so they span the full grid exactly as --wide does. Added to
   the existing full-width rule rather than stacked as a new one. */
.uks-page-shell .field-grid .form-row--wide,
.uks-page-shell .field-grid > #uks-organiser-fields,
.uks-page-shell .field-grid > #uks-venue-fields { grid-column: 1 / -1;
}
.uks-page-shell .field-grid .form-row--postcode { grid-column: 1 / -1; align-items: center;
}
.uks-page-shell .field-grid .form-row--postcode .form-input {
  width: calc((100% - 2 * var(--sp-lg)) / 3);
  margin-inline: auto;
}
.uks-page-shell .email-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-lg);
}
/* S245 row 23 (Rob, the 6th of October 2026, on the Sex at birth label: "The labels on these boxes have been centred with the asterisk. They should not be. The text should be centred and the asterisk just
   added on after."). Every .req sits at the end of its label, inside the line the label centres, so the words were pushed left of the field's centre by half the asterisk and its gap (5.6 to 6.3px, the painted
   word ink read at deviceScaleFactor 4 on every label of the checkout at 1280 and 360). Out of flow and with no offsets the asterisk keeps its own place in the line (its static position, straight after the words)
   and takes no room in it, so the centring sees the words alone. The line's word space collapses once the asterisk is no longer in the line, so margin-left carries the whole gap the asterisk had from
   the last letter (the word space and the old 2px); measured at deviceScaleFactor 4 before and after. Colour and weight are the design's (checkout.css .req), unchanged. */
.uks-page-shell .req { position: absolute; color: var(--color-gold); font-weight: 700; margin-left: 0.44em;
}
.uks-page-shell .reg-stack { display: flex; flex-direction: column; gap: var(--sp-xl);
}
.uks-page-shell .reg-textarea { min-height: 120px; resize: vertical; line-height: 1.5; text-align: left;
}
.uks-page-shell .reg-textarea::placeholder { text-align: center;
}
.uks-page-shell .reg-dd.reg-dd--wide { flex: none; width: 100%;
}
.uks-page-shell .reg-dd--wide .reg-dd__btn { justify-content: center; position: relative; padding: 11px 44px;
}
.uks-page-shell .reg-dd--wide .reg-dd__chev {
  position: absolute;
  right: 16px;
  top: 50%;
  transform: translateY(calc(-50% - 1px));
}
.uks-page-shell .reg-dd--open.reg-dd--wide .reg-dd__chev { transform: translateY(calc(-50% - 1px)) rotate(180deg);
}
.uks-page-shell .online-card { background: var(--color-surface); border-color: var(--color-gold);
}
.uks-page-shell .online-card__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 22px;
  color: var(--color-navy);
  text-align: center;
  letter-spacing: -0.01em;
  margin: 0 0 var(--sp-sm);
}
.uks-page-shell .online-card__sub {
  text-align: center;
  font-size: 14px;
  color: var(--color-gold-dark);
  margin: 0 0 var(--sp-xl);
}
.uks-page-shell .online-card .form-input { background: var(--color-surface); width: 70%; margin-inline: auto;
}
.uks-page-shell .dob-card { text-align: center;
}
.uks-page-shell .dob-card .form-hint { margin-top: var(--sp-md);
}
.uks-page-shell .dob-row {
  display: flex;
  justify-content: center;
  gap: var(--sp-md);
}
.uks-page-shell .reg-dd { position: relative; flex: 0 0 150px; width: 150px; min-width: 0;
}
/* S157: the native <select> is the value holder behind each .reg-dd (progressive
   enhancement — see assets/js/reg-dropdown.js). It is removed from view ONLY once the
   enhancer has run, so with JavaScript off the real select is still usable. Not a design
   rule: the design has no native select, this only hides our fallback. */
.uks-page-shell .reg-dd__native--enhanced {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  padding: 0;
  border: 0;
  opacity: 0;
  pointer-events: none;
  clip-path: inset(50%);
}
.uks-page-shell .reg-dd__btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  position: relative;
  min-height: 44px;
  padding: 8px 40px;
  font: 600 14px var(--font-body);
  color: var(--color-navy);
  background: var(--color-surface);
  border: 2px solid var(--color-gold);
  border-radius: var(--radius-md);
  cursor: pointer;
  text-align: center;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.10);
  transition: border-color var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out);
}
/* D-598 (S232): the checkout's Sex at birth control when the account already holds one.
   The Account page has the same lock and styles it with .workspace .form-input--readonly,
   which cannot reach the checkout, so the read-only line takes the registration shell's own
   control geometry instead: the .reg-dd__btn box, without its chevron room, its lift or its
   pointer, so it reads as a recorded value rather than as something to open. */
.uks-page-shell .reg-dd__locked {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 8px 16px;
  font: 600 14px var(--font-body);
  color: var(--color-navy);
  background: var(--color-surface);
  border: 2px solid var(--color-gold);
  border-radius: var(--radius-md);
  text-align: center;
  cursor: default;
  user-select: none;
}
/* S245 rows 22 and 15 (Rob, the 6th of October 2026: "The drop-down borders go blue when they are clicked; they should stay gold." and "The old blue border on the drop-down when it has been clicked, which is supposed to
   be gold."), D-593: "EVERY DROPDOWN KEEPS ITS GOLD BORDER WHEN OPEN ... The navy open-state rule is deleted rather than narrowed again." This was that rule: the open trigger took the navy border (measured live
   at 1280, open Day and Sex at birth: rgb(3, 27, 131)). The declaration is deleted; the trigger keeps the 2px gold border of .reg-dd__btn above, and the open state is only the deeper shadow. */
.uks-page-shell .reg-dd--open .reg-dd__btn {
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.16);
}
.uks-page-shell .reg-dd__value { line-height: 1; transform: translateY(-1px);
}
.uks-page-shell .reg-dd__value--ph { color: rgba(3, 27, 131, 0.65);
}
.uks-page-shell .reg-dd--open .reg-dd__value--ph { color: var(--color-navy);
}
.uks-page-shell .reg-dd__chev {
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  color: #DDB94B;
  position: absolute;
  right: 14px;
  top: 50%;
  transform: translateY(-50%);
  transition: transform var(--duration-fast) var(--ease-out);
}
.uks-page-shell .reg-dd--open .reg-dd__chev { transform: translateY(-50%) rotate(180deg);
}
.uks-page-shell .reg-dd__menu {
  position: absolute;
  z-index: 98;      /* S245 row 35: 98, was 1000 (header is 99; see 26.5.7) */
  top: calc(100% + 10px);
  left: 0; right: auto;
  min-width: 100%;
  width: max-content;
  max-width: 260px;
  margin: 0;
  padding: 10px;
  list-style: none;
  background: var(--color-surface);
  border: 2px solid var(--color-gold);
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
}
.uks-page-shell .reg-scroller { display: flex; flex: 1; min-width: 0; gap: 5px;
}
.uks-page-shell .reg-dd__list {
  flex: 1;
  min-width: 0;
  max-height: 260px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 4px;
  scrollbar-width: none;
}
.uks-page-shell .reg-dd__list::-webkit-scrollbar { display: none;
}
.uks-page-shell .reg-scroller__bar { width: 16px; flex: none; display: flex; flex-direction: column; align-items: center;
}
.uks-page-shell .reg-scroller__btn {
  /* S245 row 15: margin 0, the same reset .reg-dd__opt takes below. These are <button>s and the parent theme gives every button margin-bottom: 1rem (seeko-dynamic.css, 18px at the site's root size),
     which the design never had: it pushed the lower arrow 18px up and left the bar off-centre in the menu. */
  margin: 0;
  flex: none; width: 16px; height: 14px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  background: none; border: none; cursor: pointer; color: var(--color-gold);
  transition: color var(--duration-fast) var(--ease-out);
}
.uks-page-shell .reg-scroller__btn:hover { color: #b88600;
}
.uks-page-shell .reg-scroller__track {
  flex: 1; width: 12px; margin: 3px 0;
  background: #ffffff;
  border: 1.5px solid #E0C56A;
  border-radius: var(--radius-pill);
  position: relative;
}
.uks-page-shell .reg-scroller__thumb {
  position: absolute; left: 1px; right: 1px;
  min-height: 22px;
  background: #DDB94B;
  border-radius: var(--radius-pill);
  cursor: grab;
  touch-action: none;
}
.uks-page-shell .reg-scroller__thumb:active { cursor: grabbing;
}
.uks-page-shell .reg-dd__opt {
  display: flex;
  width: 100%;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 14px;
  /* S245 rows 32 and 15 (Rob, the 6th of October 2026: "to see if the blue border on these drop down options is actually correct because it looks weak and I do not think it is right"; coordinator ruling of the
     9th of October: every drop-down and its open options keep the gold border, D-593, never blue). The option border was navy at 20% (rgba(3, 27, 131, 0.2): rgb(205, 209, 230) painted on white, measured at
     deviceScaleFactor 4), the blue-grey he saw. It is the same 1.5px gold as the selected option below (--active) and as the menu's own frame (.reg-dd__menu). The option stays its own bordered control (D-593). */
  border: 1.5px solid var(--color-gold);
  border-radius: 16px;
  background: var(--color-surface);
  font: 600 13px var(--font-body);
  color: var(--color-navy);
  text-align: center;
  cursor: pointer;
  transition: background 150ms var(--ease-out), border-color 150ms var(--ease-out);
  /* S245 row 15 (Rob: "The Male and Female choices and the scroll bar are not centred within the drop-down: a big gap at the bottom, when it should be the same gap at the bottom as at the top."):
     these are <button>s and the parent theme gives every button margin-bottom: 1rem (seeko-dynamic.css, 18px here), which the design never had. It sat under every option, so under the last one it was
     18px of extra space at the foot of the list (measured live at 1280, Sex at birth: 14px above the first option, 32px below the second). The reset is the one .ev-dd__opt and .st-dd__opt carry. */
  margin: 0;
}
.uks-page-shell .reg-dd__opt span { transform: translateY(-1px); white-space: nowrap;
}
/* S245 row 14 (Rob, the 6th of October 2026: "There is no colour change on hover on the dates in the date-of-birth drop-down pickers. There needs to be a hover colour change to light cream, gold, or whatever the normal
   drop-down colours are, otherwise there is no visual indicator that you have picked the correct number."). MEASURED live with a real pointer over a Day, Month and Year option, painted pixels at deviceScaleFactor 4:
   the fill goes rgb(255, 255, 255) to rgb(255, 251, 230) and the border rgb(205, 209, 230) to rgb(204, 153, 0), a change Rob reports as none. Rows 15, 22 and 32 (his ruling, D-593) make every option's border gold
   at rest, so the border can no longer carry the hover, and a fill 5 and 25 units off white (255, 251, 230) is all that would be left of it. The hover fill is therefore the site's darker cream
   (--color-cream-hover, rgb(255, 245, 204)), the one .btn.btn--primary and .btn-option take when a cream button is hovered (42.8, 43.1): a hovered option reads as a control about to be pressed, and stays apart from the
   selected option (--active below: the light cream, bold). The border stays gold. */
.uks-page-shell .reg-dd__opt:hover { background: var(--color-cream-hover); border-color: var(--color-gold);
}
.uks-page-shell .reg-dd__opt--active { background: var(--color-cream); border-color: var(--color-gold); font-weight: 700;
}
/* S232 21/09/2026, Rob correction row 19 on the consent tick box: "Why is it so far from the
   first letter? It should be close... find the last one that was verified fixed and copy the gap
   between the inks." The verified one is the Invites panel row beside "Receive curated event
   invites" (invite-system.php 3553): a 4px flex gap, which paints 5.375px from the box's ink to
   the first letter's ink, measured at deviceScaleFactor 8. Same 4px here, and the label below no
   longer stretches, so the two read as one centred pair. .terms-card has a single instance on the
   platform, the checkout card in functions.php 8899. */
/* TICK-1 (S238, Rob, the 29th of September 2026): "This should be standard now, there are others that have been fixed
   recently, find them and make sure they all match". MEASURED on live, from four times pictures: the event form's nine
   rows (section 69, D-527) paint 12.5 to 13.0px from the box to the first letter, and the map pin beside "Minimum
   proximity distance" paints 12.75px, the gap he named as the one to match (T-S229-018). This row painted 5.5px at 1280
   (the 4px above) and, from 600px down where its words wrap to two centred lines, 13 to 17.5px with the box 10px below
   the first line. It takes the standard: 12px from the box to the words, the words' lines starting together, and the
   box on the FIRST line's capitals (the row is aligned to its top, and the box's margin in the rule below places it).
   MEASURED AFTER at 1920, 1280, 1024, 768, 600, 412 and 360: 12.25 to 13.75px, the box within 0.625px of the capital's
   centre. */
.uks-page-shell .terms-card {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: 12px;
  text-align: center;
}
.uks-page-shell .terms-card input[type="checkbox"] {
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
  accent-color: #27A644;
  cursor: pointer;
}
.uks-page-shell .terms-card__text {
  font-size: 15px;
  line-height: 1.6;
  color: var(--color-navy);
}
.uks-page-shell .terms-card__text a { color: var(--color-gold-dark); font-weight: 700; text-decoration: none;
}
/* Final verification item 17: PMPro's theme checkbox/label treatment otherwise
   replaces this one registration control with an absolutely-positioned fake box.
   Keep the proven native 20px control and centre its printed label as one row. */
.uks-page-shell #uks-legal-consent > input[type="checkbox"] {
  position: static !important;
  opacity: 1 !important;
  appearance: none !important;
  -webkit-appearance: none !important;
  display: grid !important;
  place-content: center;
  box-sizing: border-box;
  border: 2px solid var(--color-gold) !important;
  border-radius: 4px;
  background: #FFFFFF !important;
  /* TICK-1: the box's centre on the first line's capitals. The words are 0.8rem on a 1.6 line (the theme's checkout
     label size); the box and the words' first line start at the same top, and this margin is the box's drop below it.
     S245, the 9th of October 2026, FAULTS 148 (Rob, relayed: "make sure that the box is centred correctly with the first text row"). The drop was
     0.608rem less half the box, which is a fraction of a pixel (-0.27, 0.34 and 0.94px at the theme's three root sizes, 16, 17 and 18px). The browser
     pixel-snaps the box and the words' baseline separately, so a fractional drop rounds the other way on some widths: at 360 and 600 the box painted
     0.56px below the capitals' centre at deviceScaleFactor 8 and a whole 1.0px below at 1 (MEASURED live from the painted pixels: the box's outer edge
     against the first letter's cap top and baseline), while at 412 it was right. A WHOLE-pixel drop moves with the words' own rounding, so it holds on
     every width: 1rem less 17px is -1, 0 and +1px at the three root sizes, which are the drops the box already has at the widths that were right
     (1920 and 1280 +1, 1024 and 768 0, 412 -1). MEASURED after, at 1920, 1280, 1024, 768, 600, 412 and 360: the box's midpoint is +0.19 to -0.44px from
     the capitals' centre at deviceScaleFactor 8 and 0.0px at 1, every one inside the 0.5px line. */
  margin-top: calc(1rem - 17px) !important;
}
.uks-page-shell #uks-legal-consent > input[type="checkbox"]::before {
  content: "";
  width: 9px;
  height: 5px;
  border-left: 2px solid var(--color-success);
  border-bottom: 2px solid var(--color-success);
  transform: translateY(-1px) rotate(-45deg) scale(0);
  transform-origin: center;
}
.uks-page-shell #uks-legal-consent > input[type="checkbox"]:checked::before {
  transform: translateY(-1px) rotate(-45deg) scale(1);
}
.uks-page-shell #uks-legal-consent > .terms-card__text {
  width: auto !important;
  min-width: 0 !important;
  min-height: 0 !important;
  /* S232 row 19. flex: 1 1 0 made this label fill every pixel the box left over, and the card
     centres its text, so the first letter's ink stood 133.375px from the box at 1280 however
     small the gap was set. It shrink-wraps now, so the box and the words are one centred pair.
     max-width keeps the pair on ONE flex line: a wrap container breaks the line on the item's
     hypothetical size, and an unclamped shrink-wrapped label is wider than a phone, which put
     the box on a line of its own at 360 and 414. 24px is this row's own 20px box plus its 4px
     gap. MEASURED AFTER at deviceScaleFactor 8: ink gap 5.375px, the same as the reference. */
  flex: 0 1 auto !important;
  /* TICK-1: 32px is this row's 20px box and its 12px gap (it was 24px for the 4px gap). */
  max-width: calc(100% - 32px) !important;
  padding-left: 0 !important;
  margin: 0 !important;
  /* TICK-1: the lines of a wrapped label start together, beside the box (they were centred, which put the first
     letter up to 17.5px from the box on a phone). The box is placed against the first line by its own margin above,
     so the S232 nudge of the words (0.1875px) is not needed. */
  text-align: left !important;
  transform: none !important;
}
.uks-page-shell #uks-legal-consent > .terms-card__text::before,
.uks-page-shell #uks-legal-consent > .terms-card__text::after {
  content: none !important;
}
/* S157: the consent VALIDATION state. The design mock has no error state (it is a
   static prototype), so these rules are additive — they set properties the design's
   .terms-card rule does not set, and never override one it does. The error message is
   a third flex child that must take its own line. Brand error token, not a new hex. */
.uks-page-shell .terms-card { flex-wrap: wrap; }
.uks-page-shell .terms-card--error { border-color: var(--color-error); }
.uks-page-shell .terms-card__error {
  flex: 0 0 100%;
  margin-top: var(--sp-sm);
  padding: 8px 12px;
  border: 1px solid var(--color-error);
  border-radius: var(--radius-md);
  background: rgba(196, 28, 28, 0.06);
  color: var(--color-error);
  font-weight: 700;
  font-size: 13px;
  text-align: center;
}
.uks-page-shell .notice-card {
  background: var(--color-cream);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: var(--sp-xl) var(--sp-2xl);
  margin-top: var(--sp-xl);
}
.uks-page-shell .notice-card__text {
  font-size: 14px;
  line-height: 1.7;
  color: var(--color-navy);
  text-align: center;
  text-wrap: pretty;
  margin: 0;
}
.uks-page-shell .checkout-submit {
  display: flex;
  justify-content: center;
  margin-top: var(--sp-2xl);
  /* S238 F03c (the 28th of September 2026): the positioning context for PMPro's Processing
     block below, so the button is the row's only flex item. */
  position: relative;
}
/* S238 F03c (the 28th of September 2026). PMPro prints #pmpro_processing_message inside this
   row (checkout.php, inline visibility: hidden) and only toggles its visibility, so hidden it
   still took a flex slot: 92 to 104px beside the button pushed the button 55 to 61px left of
   the form's centre from 1920 to 600, and at 360 it wrapped under the button and added 43.6px
   of invisible height. Out of flow it takes no slot and no height, hidden or shown; when PMPro
   shows it (pmpro-checkout.js, pmpro-stripe.js) it paints centred under the button, one PMPro
   row gap below it (--pmpro--base--spacing--medium, 18px, exactly where it already painted at
   360), and the button never moves. Every script finds it by id; the 25.1 Terms check
   (display none) and the 29.x release (visibility hidden) still hide it. */
.uks-page-shell .checkout-submit #pmpro_processing_message {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  margin-top: var(--pmpro--base--spacing--medium, 18px);
  /* S245 row 25 (Rob, the 6th of October 2026: "Just plain text "Processing..."? That is obviously wrong and needs to be properly styled."): the waiting line takes the look this checkout already gives its own
     message boxes, copied value for value: the white box, 2px gold border and 12px radius of #pmpro_message (functions.php, uks-pmpro-checkout-css, "PMPro error/info messages"), its 12px 16px padding and
     Nunito Sans 600, and the navy text on white Rob chose for the waiting state ("WAIT-2", the 28th of September 2026: white with the gold border and navy text). It shrinks to its words and sits centred
     under the button (left and right stay 0, the auto side margins centre it); PMPro still only toggles its visibility, so hidden it paints nothing and takes no room. */
  width: fit-content;
  margin-inline: auto;
  padding: 12px 16px;
  background: var(--color-surface);
  border: 2px solid var(--color-gold);
  border-radius: 12px;
  color: var(--color-navy);
  font-family: var(--font-body);
  font-weight: 600;
  text-align: center;
}
.uks-page-shell .checkout-submit .btn--primary {
  font-size: 15px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 15px 40px;
}
/* S245 row 33 (Rob, the 6th of October 2026: "The submit button seems to have the wrong clicked animation too."). MEASURED live on the enabled Submit held down at 1280: a white fill (functions.php paints
   `#pmpro_form .pmpro_btn:hover` and `#pmpro_btn-submit:hover` #fff !important, and both still match while the button is pressed), opacity .7 from PMPro's own `.pmpro_btn:active` (variation_1.css 168), no shadow and
   no lift: a faded white button. The Submit is a <button> (the rules at 70.6 below, `#pmpro_form input.pmpro_btn`, were written for an input[type=submit] and never reach it), so it had no pressed look of its own. It takes the one pressed look D-640
   gives every button, the same values as the held Apply button below and .btn.btn--primary:active at 42.8: the darker cream, the gold border, the navy label, no shadow, no lift, full opacity.
   The id selector (1,2,1) and !important are what outrank the inline !important fill (1,2,0). Rest and hover are not touched. */
#pmpro_form button.pmpro_btn-submit-checkout:active {
  background: var(--color-cream-hover) !important;
  border-color: var(--color-gold) !important;
  color: var(--color-navy) !important;
  box-shadow: none;
  transform: none;
  opacity: 1;
}
/* S238 F03e (the 28th of September 2026), Rob: "the chevrons clearly aren't centred and sit high
   compared to the letters". The label renders in Arial Bold (the sans-serif fallback; no Montserrat
   face loads on the checkout), whose chevron ink is centred 0.2571em above the baseline while the
   capitals are centred at 0.3579em (half the 0.716em cap height): the chevron needs raising by
   about 0.101em (1.41px at the 14px label). The old fixed 2px overshot by about 0.6px, the "sits
   high" Rob saw (0.6px at 4x, 0.75px at 2x). 0.111em (1.55px) rounds to 6 device pixels at 4x,
   3 at 2x and 2 at 1x: the chevron's ink midpoint lands 0.125px from the capitals' at 4x,
   0.25px at 2x and exactly on it at 100% (where 0.1em would round down to 1px and paint a whole
   pixel low); at 125% and 150% it is never further off than before. In em so it follows the
   font size; Montserrat 700 would need about 0.086em. A transform moves only the paint, so the
   button's size and the label's horizontal centring are untouched. */
.uks-page-shell .submit-chev { display: inline-block; transform: translateY(-0.111em);
}
@container vp (max-width: 768px) {
  .uks-page-shell .level-card__change { padding-top: 7px; padding-bottom: 9px;
  }
}
@container vp (max-width: 767px) {
  .uks-page-shell .field-grid { grid-template-columns: 1fr 1fr;
  }
  /* S159: same reason as the desktop rule above - these fieldsets are grid ITEMS. */
  .uks-page-shell .field-grid .form-row--wide,
  .uks-page-shell .field-grid > #uks-organiser-fields,
  .uks-page-shell .field-grid > #uks-venue-fields { grid-column: 1 / -1;
  }
}
@container vp (min-width: 481px) and (max-width: 767px) {
  .uks-page-shell .field-grid .form-row--half:first-child { grid-column: 1 / -1;
  }
}
@container vp (max-width: 480px) {
  .uks-page-shell .field-grid { grid-template-columns: 1fr;
  }
  .uks-page-shell .email-row { grid-template-columns: 1fr;
  }
  .uks-page-shell .reg-dd { flex: 1 1 0; width: auto; min-width: 0;
  }
  .uks-page-shell .reg-dd__btn { padding-left: 12px; padding-right: 12px;
  }
}
/* §70.4 Print rules. The design specifies the CTA is on-screen only and must not
   appear on the printed/PDF invoice ("hide it in the print stylesheet"). */
@media print {
  .uks-page-shell .receipt__foot { display: none; }
  .uks-page-shell .receipt__head .btn--subtle { display: none; }
  .uks-page-shell .confirm-shell { padding: 0; background: #fff; }
}

/* §70.5 Suppress the theme's own page-title header on the two ported standalone
   pages. The design supplies its own .confirm-shell__title, so the theme's
   .svq-page-header h1 renders the page name a second time directly above it.
   Scoped to the two PMPro body classes so no other page is affected. */
body.pmpro-confirmation .svq-page-header,
body.pmpro-checkout .svq-page-header,
body.page-id-41 .svq-page-header,
body.page-id-40 .svq-page-header { display: none; }

/* §70.6 REGISTRATION — mapping the design's layout onto PMPro's real DOM.
   PMPro emits its own wrappers (.pmpro_card, .pmpro_form_fields, .pmpro_cols-2,
   input.pmpro_btn) rather than the design's class names. The design's rule BODIES
   below are unchanged; they are simply applied to the selectors PMPro actually
   renders. This is the sanctioned cascade-fix, not an edit to the design. */

/* Un-nest PMPro's double card so the page reads as the design's single card. */
.uks-registration .pmpro_card { background: none; border: 0; box-shadow: none; padding: 0; margin: 0; }
.uks-registration .pmpro_card_content { padding: 0; }
.uks-registration section > .pmpro_form > fieldset {
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: var(--sp-xl);
  box-shadow: var(--shadow-sm);
  margin: 0 0 var(--sp-xl);
}

/* Level card (design .level-card / .level-card__title / .level-card__body). */
.uks-registration #pmpro_pricing_fields { text-align: center; }
.uks-registration #pmpro_pricing_fields .pmpro_form_heading,
.uks-registration #pmpro_user_fields .pmpro_form_heading {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 22px;
  color: var(--color-navy);
  text-align: center;
  letter-spacing: -0.01em;
  margin: 0 0 var(--sp-xl);
}
.uks-registration #pmpro_pricing_fields .pmpro_level_cost,
.uks-registration #pmpro_pricing_fields p {
  text-align: center;
  font-size: 16px;
  line-height: 1.7;
  color: var(--color-navy);
  margin: 0;
  text-wrap: pretty;
}
.uks-registration #pmpro_pricing_fields strong { color: var(--color-gold); font-weight: 700; }

/* S157 — DELETED, not disabled: the field-grid shadow rules that used to live here.
   §70.6's whole premise was "PMPro emits its own wrappers rather than the design's
   class names", so it re-applied the design's rule bodies to PMPro's selectors. The
   template now emits the design's OWN classes (.field-grid / .form-row--half /
   .form-row--wide / .email-row / .form-row--postcode), so §70.3's ported rules do the
   job directly and these were pure duplication.

   They were also actively harmful, which is how this was found: the rule
     .uks-registration #pmpro_user_fields .pmpro_form_fields > div { grid-column: span 1 }
   matched EVERY direct child at (1,2,1) and beat the design's own
     .uks-page-shell .field-grid .form-row--wide { grid-column: 1 / -1 }
   at (0,3,0). The e-mail pair was pinned into a single 226px track, rendering two ~95px
   inputs on a 708px row. Deleting the shadow lets the design's rule win on its own.
   The .pmpro_cols-2 rules went with them: the template no longer emits that wrapper.
   The postcode rule went too, and had never matched anything - it targeted
   `.pmpro_checkout-field-uks_postcode` (underscore) while the field renders
   `pmpro_checkout-field-uks-postcode` (hyphen). The design's
   `.field-grid .form-row--postcode .form-input` rule is what sizes it now.
   PMPro's label/input treatment below is KEPT: the billing and gateway fieldsets are
   still PMPro's own markup and are not modelled by the design. */

/* The ONE cascade fix the deletion left behind, and it is a scope-bump on the design's
   OWN selector, not a re-implementation: the grid container carries both .field-grid
   (design) and .pmpro_form_fields (PMPro), and PMPro sets `display: flex` on its class,
   which was beating the design's `display: grid`. MEASURED, not assumed: computed
   display was `flex` while grid-template-columns still read the unresolved
   `repeat(3, 1fr)` - the tell that the element was never laid out as a grid, which is
   why every child rendered full-width despite correctly computing `grid-column: span 1`.
   With the ID scope the design's own value wins and the tracks resolve to 3 x 224px. */
.uks-registration #pmpro_user_fields .field-grid {
  display: grid !important;
}

/* Every PMPro label + input takes the design's form-* treatment. */
.uks-registration #pmpro_user_fields label,
.uks-registration .pmpro_checkout-field label {
  display: block;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 13px;
  color: var(--color-navy);
  letter-spacing: 0.01em;
  text-align: center;
  margin: 0 0 6px;
}
.uks-registration input[type="text"],
.uks-registration input[type="email"],
.uks-registration input[type="password"],
.uks-registration select,
.uks-registration textarea {
  width: 100%;
  padding: 11px 14px;
  font: 400 14px var(--font-body);
  color: var(--color-navy);
  background: var(--color-surface);
  border: 2px solid var(--color-gold);
  border-radius: var(--radius-md);
  outline: none;
  text-align: center;
  margin-bottom: 0;
  box-shadow: none;
  height: auto;
}
html[data-nav="kbd"] .uks-registration input:focus,
html[data-nav="kbd"] .uks-registration select:focus {
  box-shadow: 0 0 0 2px rgba(204, 153, 0, 0.25) !important;
  border-color: var(--color-gold);
  outline: none;
}
.uks-registration .pmpro_form_hint,
.uks-registration .lite-hint,
.uks-registration small { font-size: 12px; color: var(--color-text-secondary); text-align: center; display: block; }

/* PMPro's show/hide password eye sits inline with the label and breaks the row. */
.uks-registration .pmpro_form_field-password { position: relative; }
.uks-registration .pmpro_form_field-password button,
.uks-registration .pmpro_password_toggle {
  position: absolute;
  /* S245 row 10: right: 10px and bottom: 7px pinned the eye to the field's corner when this rule was the whole story. 70.11 below has long since made the eye a relative item in the label row
     (position: relative !important, top: 1.19px !important), and a relatively positioned box still honours right: it was moved 10px to the LEFT of its place, back over the label's gold
     asterisk (measured live at 1280: the eye's box 10px left of its wrapper, its ink touching the asterisk, which is the crowding Rob sees). Deleted, not narrowed; bottom lost to top already. */
  background: none;
  border: 0;
  box-shadow: none;
  padding: 4px;
  margin: 0;
  min-height: 0;
  color: var(--color-gold);
}

/* Submit — the design's .btn--primary. Seeko/PMPro paint it solid gold, and the
   competing rule sets background, colour AND border-color, so all three are set
   here (Rule 12: defeat every property the competing rule touches). */
#pmpro_form input.pmpro_btn,
#pmpro_form input.pmpro_btn-submit-checkout,
#pmpro_form .pmpro_form_submit input[type="submit"] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1;
  padding: 15px 40px;
  border-radius: 10px;
  background: var(--color-cream) !important;
  border: 2px solid var(--color-gold) !important;
  color: var(--color-navy) !important;
  box-shadow: 0 2px 6px rgba(3,27,131,.08), 0 3px 10px rgba(204,153,0,.16);
  cursor: pointer;
  margin-bottom: 0;
  width: auto;
  transition: all var(--duration-fast) var(--ease-out);
}
/* S245 row 4 (Rob, the 6th of October 2026, on Apply: "The apply button was wrong on click, the animation and colours."). MEASURED live on the discount code's Apply button, held down at 1280: the press kept the hover
   lift (translateY(-2px)) and the large two-layer shadow (this rule still matched while it was held), and PMPro's own `.pmpro_btn:active { opacity: .7 }` (variation_1.css 168) faded the label, so a pressed Apply read as
   a washed-out lavender button. While PMPro's apply call runs the button is disabled (pmpro-checkout.js 43) and theme-static's `input[type=button]:disabled { opacity: .65 }` fades it the same way. The hover now belongs to a
   real, un-held, enabled button (:hover:not(:active):not(:disabled), the gate .btn.btn--primary uses at 42.8, S244 row 119) and the pressed and in-flight look is the one look D-640 gives every button: the darker cream, the
   gold border, the navy label, no shadow, no lift, full opacity (.btn-option:active at 43.1 and .btn.btn--primary:active at 42.8 carry the same). The id selector (1,2,1) and !important outrank the inline !important fill. */
#pmpro_form input.pmpro_btn:hover:not(:active):not(:disabled),
#pmpro_form .pmpro_form_submit input[type="submit"]:hover:not(:active):not(:disabled) {
  background: var(--color-cream-hover) !important;
  border-color: var(--color-gold) !important;
  color: var(--color-navy) !important;
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(3,27,131,.10), 0 8px 24px rgba(204,153,0,.28);
}
#pmpro_form input.pmpro_btn:active,
#pmpro_form input.pmpro_btn:disabled,
#pmpro_form .pmpro_form_submit input[type="submit"]:active,
#pmpro_form .pmpro_form_submit input[type="submit"]:disabled {
  background: var(--color-cream-hover) !important;
  border-color: var(--color-gold) !important;
  color: var(--color-navy) !important;
  box-shadow: none;
  transform: none;
  opacity: 1;
}
.uks-registration .pmpro_form_submit { display: flex; justify-content: center; margin-top: var(--sp-2xl); }
.uks-registration .pmpro_form_submit .pmpro_btn-cancel { display: none; }

@container vp (max-width: 767px) {
  .uks-registration #pmpro_user_fields .pmpro_form_fields { grid-template-columns: 1fr 1fr; }
}
@container vp (min-width: 481px) and (max-width: 767px) {
  .uks-registration #pmpro_user_fields .pmpro_form_fields > div:first-child { grid-column: 1 / -1; }
}
@container vp (max-width: 480px) {
  .uks-registration #pmpro_user_fields .pmpro_form_fields { grid-template-columns: 1fr; }
  .uks-registration .pmpro_checkout-field-uks_postcode input[type="text"] { width: 100%; }
}

/* §70.7 Width chain. Measured on live: .checkout-page is the design's 760px, but
   PMPro/Seeko then shed width at four levels (form 560, card 486, card_content 484,
   form_fields 412), which crushed the 3-column field grid to ~127px tracks. Each
   level is forced back to full width so the design's grid gets the space it needs. */
.uks-registration .pmpro_form,
.uks-registration .pmpro_section,
.uks-registration .pmpro_form_fieldset,
.uks-registration .pmpro_card,
.uks-registration .pmpro_card_content,
.uks-registration .pmpro_form_fields,
.uks-registration #pmpro_user_fields,
.uks-registration #pmpro_pricing_fields {
  width: 100%;
  max-width: 100%;
  margin-left: 0;
  margin-right: 0;
  float: none;
}
.uks-registration .pmpro_form,
.uks-registration .pmpro_card,
.uks-registration .pmpro_card_content { padding-left: 0; padding-right: 0; }

/* §70.8 The §70.7 width rules lost the same cascade fight the submit button lost:
   a class-level selector is outranked here, and the winning competitor is only
   beaten by an ID scope. PMPro gives the form and both fieldsets real IDs, so use
   them. (Verified by screenshot, not getComputedStyle: see LB-177.)
   S238 PAY-1b: this is the Registration width chain, and #pmpro_form is also the card-change form on /billing/ (PMPro's
   on-site Stripe form since PAY-1). There it stripped the form card's own side padding to 0, so the refusal notice
   and the buttons sat hard on the card's gold edge (measured at 1280: notice x 361 inside a card at x 360). The
   #pmpro_form lines now stop at the billing page; :where() adds no weight, so every other page keeps this rule
   exactly as it was. 71.4 lays the billing form out as the page's own card. */
:where(body:not(.pmpro-billing)) #pmpro_form,
:where(body:not(.pmpro-billing)) #pmpro_form .pmpro_form_fieldset,
:where(body:not(.pmpro-billing)) #pmpro_form .pmpro_card,
:where(body:not(.pmpro-billing)) #pmpro_form .pmpro_card_content,
:where(body:not(.pmpro-billing)) #pmpro_form .pmpro_form_fields,
#pmpro_user_fields,
#pmpro_user_fields .pmpro_card,
#pmpro_user_fields .pmpro_card_content,
#pmpro_user_fields .pmpro_form_fields,
#pmpro_pricing_fields,
#pmpro_pricing_fields .pmpro_card,
#pmpro_pricing_fields .pmpro_card_content {
  width: 100% !important;
  max-width: 100% !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
  padding-left: 0 !important;
  padding-right: 0 !important;
  float: none !important;
}
/* The card frame lives on the fieldset, so give that one back its inner padding. (S238 PAY-1b: not on /billing/,
   where PMPro's fieldset sits inside the form card and this padding was a second 24px frame inside it.) */
:where(body:not(.pmpro-billing)) #pmpro_form .pmpro_form_fieldset {
  padding: var(--sp-xl) !important;
  box-sizing: border-box;
}

/* §70.9 Two remaining measured gaps on the Registration field row.
   (a) .pmpro_section still insets the form by 100px a side (760 -> 560), so the
       grid never gets the design's full 760px column.
   (b) PMPro's .pmpro_cols-2 pair wrappers were still computing grid-column: span 1,
       so password+confirm and email+confirm were squeezed into ONE 158px track each
       instead of spanning the row. Matching the design's .field-grid: the password
       pair sits beside Username on row 1 (span 2), the email pair takes its own
       full-width row. ID-scoped because class-level selectors lose here (LB-177). */
.uks-registration .pmpro_section,
.uks-registration section[class*="pmpro_section"] {
  padding-left: 0 !important;
  padding-right: 0 !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
  width: 100% !important;
  max-width: 100% !important;
}
/* S157: the three .pmpro_cols-2 rules that used to live here are DELETED, not disabled.
   They existed to force PMPro's pair wrappers to span the grid; the template no longer
   emits .pmpro_cols-2 at all (the design lays the fields out as .form-row--half cells),
   so they matched nothing. Dead code goes (D-243 principle 4).

   What replaces them is the actual width fix. MEASURED on live, not assumed: #pmpro_form
   computed width AND max-width both resolved to 560px inside a 760px .checkout-page,
   so the grid only ever had 460px and its three tracks came out at 142px. §70.8's bare
   `#pmpro_form` rule was losing, and a CSSOM walk could not name the winner (LB-177 -
   the walk returns nothing readable on this page under any instrument I tried). Rather
   than keep guessing at the competitor, the fix was proven empirically in the live page:
   adding the .uks-registration class scope (1 ID + 1 class) wins, and max-width must be
   `none` rather than 100% because the competitor sets an explicit px value.
   Result, measured: form 560 -> 760, grid 460 -> 708, tracks 142px -> 225px. */
.uks-registration #pmpro_form {
  width: 100% !important;
  max-width: none !important;
}
/* S157: the card FRAME moved. §70.8 above gave the padding to PMPro's fieldset because
   in S136 the fieldset was the visual card. The template now puts the design's own
   .card on the inner div (account) and on #pmpro_pricing_fields (level), so the frame
   and its padding belong there. The fieldset and PMPro's card_content are flattened to
   nothing, and the two elements that DO carry .card get the design's 24px back. */
.uks-registration #pmpro_user_fields,
.uks-registration #pmpro_payment_information_fields,
.uks-registration #pmpro_form .pmpro_card_content {
  padding: 0 !important;
  border: 0 !important;
  background: none !important;
  box-shadow: none !important;
}
/* §70.8a S238 PAY-1 (Rob, the 27th of September 2026): the on-site card box (functions.php 29.3) is built like the
   Account Information card, PMPro's fieldset outside and the design's .card inside, and the rule above flattens the
   fieldset exactly as it flattens #pmpro_user_fields. Two more stock values reach it, and each is replaced at its
   source rather than out-ranked:
   - the Seeko parent theme lays #pmpro_payment_information_fields out as a wrapping flex row (seeko
     paid-memberships-pro/css/frontend.min.css), which shrinks the .card inside it to its content, so the .card takes
     the whole row; the fieldset keeps its own display, so PMPro's discount-code script can still hide and show it;
   - PMPro frames its three card mount points from its own tokens (css/frontend/base.css and variation_1.css: 1px solid
     var(--pmpro--color--border), var(--pmpro--base--border-radius), calc(var(--pmpro--base--spacing--small) + 3px),
     white). Those tokens are pointed at the brand tokens for this box only, the way 71 points them for the billing
     page, so the boxes Stripe's fields sit in read as the page's own fields: gold border, the design radius, 11px.
   Measured with the live CSS in headless Chromium (S238 PAY-1 harness/render). Visual sign-off is the visual lane's. */
.uks-registration #pmpro_payment_information_fields {
  --pmpro--color--border: var(--color-gold);
  --pmpro--base--border-radius: var(--radius-md);
  --pmpro--base--spacing--small: 8px;
}
.uks-registration #pmpro_payment_information_fields > .card {
  flex: 1 1 100%;
}
/* S238 PAY-1b: the three boxes Stripe's card fields sit in, on the Registration card box AND on the /billing/ card
   form, drawn as the page's own .form-input (#username: 2px gold, var(--radius-md), 45px tall at 1280). The colour and
   the radius already come from the tokens above (and from 71 on /billing/). The WIDTH of PMPro's border is not a token:
   PMPro writes "1px solid" into its own id-level rules for these boxes (css/frontend/base.css and variation_1.css),
   so only the width and the padding are replaced here, by id, with !important, as PMPro's files cannot be edited.
   12px above and below Stripe's 16.8px iframe = 44.8px, #username's 45 within 1px.
   Measured before: 1px and 40.8px tall on the checkout; 1px and 48.8px tall on /billing/. */
:is(.uks-registration, body.pmpro-billing) #pmpro_payment_information_fields :is(#AccountNumber, #Expiry, #CVV) {
  border-width: 2px !important;
  border-style: solid !important;
  padding: 12px 14px !important;
  box-sizing: border-box;
}
/* §70.8b S238 PAY-1b (Rob, the 27th of September 2026: keep Apple Pay and Google Pay): the wallet row of the card box
   (functions.php 29.3a). PMPro's pmpro-stripe.js draws Apple Pay or Google Pay into #payment-request-button only when
   the browser can pay with one; functions.php 29.4 then marks the row uks-wallet-row--ready. Until then the row takes
   no space and shows nothing (the mount point itself is never hidden, so Stripe always has a box to draw in). When a
   wallet is there: the button fills the row as Card Number does, and a centred "Or pay with card" sits under it
   between two gold hairlines (the card-title rule idiom: gold, 1.5px, 1px radius), in the field-label face. The cover
   is a transparent button over the wallet button while the rest of the form is not ready (29.4); it has no look of
   its own, only a navy focus ring for the keyboard. Seeko's global button rule (margin-bottom 1rem, #f8f8f8, 0.5rem
   1rem padding) is replaced on it, not inherited. The row is a design .form-row (a centred flex column), so it is
   told to stretch, or the wallet button would shrink to nothing. Measured at 1280, 768 and 360 in headless Chromium with
   a stand-in wallet frame (harness out/e_checkout_*.png): button and cover the full field width, divider text centred. */
.uks-registration .uks-wallet-row {
  align-items: stretch;
  gap: 0;
  margin-top: 0;
  margin-bottom: 0;   /* top and bottom only: the side margins stay those of every .form-row (-5px), so the wallet
                         button lines up with the card fields' outer edges below it */
}
.uks-registration .uks-wallet-row--ready {
  margin-bottom: var(--sp-xl);
}
.uks-registration .uks-wallet-button {
  position: relative;
  width: 100%;
}
/* PMPro holds its wallet button to half the row (max-width: 50%, css/frontend/base.css, an id-level rule); Stripe's own
   hosted page, which members used until PAY-1, shows it the full width of the form above "Or pay with card", and the
   cover must lie exactly over it, so the half-width cap is replaced for this box. */
.uks-registration #pmpro_payment_information_fields #payment-request-button {
  max-width: none !important;
  width: 100%;
}
.uks-registration .uks-wallet-cover {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: block;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 4px;
  background: transparent;
  box-shadow: none;
  cursor: pointer;
}
.uks-registration .uks-wallet-cover[hidden],
.uks-registration .uks-wallet-row:not(.uks-wallet-row--ready) .uks-wallet-cover {
  display: none;
}
.uks-registration .uks-wallet-cover:focus-visible {
  outline: 2px solid var(--color-navy);
  outline-offset: 2px;
}
.uks-registration .uks-wallet-divider {
  display: none;
}
.uks-registration .uks-wallet-row--ready .uks-wallet-divider {
  display: flex;
  align-items: center;
  gap: var(--sp-md);
  margin: var(--sp-lg) 0 0;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 13px;
  line-height: 1.2;
  letter-spacing: 0.01em;
  color: var(--color-navy);
  text-align: center;
}
.uks-registration .uks-wallet-row--ready .uks-wallet-divider::before,
.uks-registration .uks-wallet-row--ready .uks-wallet-divider::after {
  content: "";
  flex: 1 1 0;
  height: 1.5px;
  border-radius: 1px;
  background: var(--color-gold);
}
.uks-registration #pmpro_form .card,
.uks-registration #pmpro_pricing_fields.card {
  padding: var(--sp-xl) !important;
  box-sizing: border-box;
}

/* §70.10 Remaining Registration deltas against the design.
   - Level card: centre the stack and give the Change-level button the design's
     .level-card__change treatment (cream pill, margins per checkout.css).
   - Password toggle: PMPro's eye button was escaping its field and floating over
     the Account Information heading. Its wrapper has zero width, so the button is
     pinned to the field itself instead.
   - Postcode: the design shows it at one-third width, centred on its own row.
   - Date of birth: the design gives it its OWN card (.dob-card), so it is lifted
     out of the account card's visual block with its own frame. */
#pmpro_pricing_fields .pmpro_card_content { text-align: center; }
.uks-registration .level-card__change {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin: var(--sp-md) auto var(--sp-lg);
  border-radius: 999px;
  padding: 6px 16px 10px;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 13px;
  line-height: 1;
  background: var(--color-cream);
  border: 2px solid var(--color-gold);
  color: var(--color-navy);
  text-decoration: none;
  box-shadow: 0 2px 6px rgba(3,27,131,.08), 0 3px 10px rgba(204,153,0,.16);
  transition: all var(--duration-fast) var(--ease-out);
}
.uks-registration .level-card__change:hover {
  background: var(--color-cream-hover);
  color: var(--color-navy);
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(3,27,131,.10), 0 8px 24px rgba(204,153,0,.28);
}

/* R3-Q (24/09/2026, item 5): the two rules this used to set (.pmpro_form_field-password-toggle,
   .pmpro_btn-password-toggle) were always beaten by the more specific §70.11 block below, which
   shares this exact selector list and runs later in the file - dead weight kept only
   "position: relative" alive, and §70.11 restates that with !important anyway. Removed rather
   than left stacked on top of the rule that actually wins (Rule of one, item 32). */

#pmpro_user_fields .pmpro_checkout-field-uks-postcode input[type="text"] {
  width: calc((100% - 2 * var(--sp-lg)) / 3) !important;
  margin-inline: auto !important;
  display: block;
}

/* DOB as its own card, matching .dob-card. */
#pmpro_user_fields .pmpro_checkout-field-uks-dob {
  background: var(--color-surface);
  border: 1.5px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: var(--sp-xl);
  box-shadow: var(--shadow-sm);
  margin-top: var(--sp-lg);
  text-align: center;
}
#pmpro_user_fields .uks-dob-row {
  display: flex;
  justify-content: center;
  gap: var(--sp-md);
  flex-wrap: wrap;
}
#pmpro_user_fields .uks-dob-row select { width: auto !important; min-width: 110px; }
#pmpro_user_fields .pmpro_checkout-field-uks-dob small { margin-top: var(--sp-md); }

@container vp (max-width: 480px) {
  #pmpro_user_fields .pmpro_checkout-field-uks-postcode input[type="text"] { width: 100% !important; }
}

/* §70.11 The password eye (R3-Q 24/09/2026, item 5, D-640; top nudge corrected INK-ROBUST
   25/09/2026, then R3-05c 25/09/2026 third attempt). Matches the platform's established
   icon-to-label gap (6px, R3-05's login fix) instead of pinning the eye to the FIELD's
   bottom-right corner, which read as "miles away" from the word "Password" once the label sits
   above the input (measured live: button top 749 vs field top 783, escaping the field
   entirely). The field wrapper is now the flex row itself: label, then the toggle, 6px apart
   and centred on the label's line, with the input pushed onto its own full-width line below.
   Confirm Password reuses this same .pmpro_form_field-password class with no toggle inside it,
   so the rule degrades there to a plain label-then-input stack, harmless. The icon's own size
   and colour are inherited from the global .pmpro_icon-eye svg rule (functions.php, R3-05c:
   12px, colour stated explicitly alongside stroke) rather than restated here - one rule per
   property. flex-direction is stated explicitly because .uks-page-shell .form-row (S. earlier,
   checkout wraps this same field in .form-row) sets flex-direction: column with no !important -
   this was the ONLY declaration for that property until now, so it silently won and stacked the
   toggle as a THIRD row between the label and the input until row was restated here.
   R3-05c (25/09/2026, gate 12 "reference" mode, third attempt on item 5): top recomputed for
   the smaller 12px icon (see functions.php's #pmpro_btn-password-toggle-1 comment for the full
   rationale, including the two gate bugs found and reported rather than fixed here - out of
   this item's scope). Checkout's label sits at a different y than login's and measures its own
   shorter capital height (9px against login's 10px), so the two pages do not share one top
   offset even though they share one icon size: 0.5px -> 1.19px, verified by direct
   correct-divisor measurement (results/s235/r3-05c/probe6.js) to land the ink midline within
   0.4px of the "P" midline on both required rasters (412w dpr2.625, 360w dpr3), and by direct
   screenshot (results/s235/r3-05c/final_checkout.png). Gate 12 itself cannot certify this value
   (see functions.php comment); its own measurement is reported to the coordinator alongside
   this item, not silently accepted or argued with. */
/* S245 rows 10 and 95 (Rob, the 6th of October 2026: "Password and confirm password labels are not centred. The password label eye icon is not in the best place either, given that there is a mandatory
   gold asterisk there as well."; and the meter verification of the 8th of October: the first keystroke drops Confirm Password 31px below Password).
   MEASURED live at 1280 before this change: the wrapper was a wrapping flex ROW with the label and the eye on its first line, left-aligned, so the words Password and Confirm Password sat 82.0px and 63.1px
   left of their field's centre (painted word ink at deviceScaleFactor 4; Username, E-mail and Postcode sat 5.6 to 5.9px left, the asterisk, row 23). And when the strength meter is moved into the Password field by the first keystroke it becomes a fourth line, the Password cell
   grows by 41.6px, the grid row stretches the Confirm Password cell to match, and its wrapping lines (align-content: normal, which stretches) share the extra height: the input drops 31.2px.
   One grid now holds both cells the same way: a row of three columns (1fr auto 1fr) so the label, in the middle column, is centred on the field exactly, with the eye (the platform's established 6px
   icon-to-label gap, D-640 "icons sit close to their labels") in the column on its LEFT, hugging the words, so it no longer sits against the gold asterisk, which hangs off the words on the right (row 23).
   The input takes the full width of the row below, the meter the row below that, and align-content: start means no row is ever stretched, so nothing can drop. Confirm Password has no eye and uses the same grid,
   so the two labels centre identically. The eye's own box and its ink alignment are the 70.11 button rule below, unchanged. */
#pmpro_user_fields .pmpro_form_field-password {
  position: relative !important;
  display: grid !important;
  grid-template-columns: 1fr auto 1fr !important;
  align-items: center !important;
  align-content: start !important;
  gap: 6px !important;
}
#pmpro_user_fields .pmpro_form_field-password > label { grid-column: 2 !important; grid-row: 1 !important; }
#pmpro_user_fields .pmpro_form_field-password-toggle {
  grid-column: 1 !important;
  grid-row: 1 !important;
  justify-self: end !important;
  position: static !important;
  width: auto !important;
  height: auto !important;
  overflow: visible !important;
}
#pmpro_user_fields .pmpro_form_field-password > input { grid-column: 1 / -1 !important; grid-row: 2 !important; }
#pmpro_user_fields .pmpro_form_field-password > #pass-strength-result { grid-column: 1 / -1 !important; grid-row: 3 !important; }
#pmpro_user_fields button.pmpro_btn-password-toggle {
  position: relative !important;
  top: 1.19px !important;
  /* S245 row 10: the eye is centred on the capital P of the label by its INK (the R3-05c reference, results/s235/r3-05c). Measured at deviceScaleFactor 4 at 1280 after the grid above: the P's capital
     band midline falls on a half pixel and the eye's ink (an even height) can only sit on a whole one by layout, so the eye read +0.5px low (top: 1.19px and 0.94px both landed on a whole pixel, +0.50 and -0.50).
     A transform is composited and keeps its fraction, so the last half pixel is a transform and not a layout offset: -0.5px measured 0.00px. */
  transform: translateY(-0.5px) !important;
  width: auto !important;
  height: auto !important;
  min-width: 0 !important;
  min-height: 0 !important;
  padding: 0 !important;
  margin: 0 !important;
  background: none !important;
  border: 0 !important;
  box-shadow: none !important;
  border-radius: 0 !important;
  color: var(--color-gold) !important;
  font-size: 0 !important;
  line-height: 0 !important;
  display: flex !important;
  align-items: center;
  justify-content: center;
  z-index: 3;
}

/* §70.12 These two are STANDALONE pages, so the design's own .confirm-shell
   padding should govern the gutter, not the theme's article chrome. Measured at
   360: the theme stacked container 30px + col-main 15px + entry-content 8px on
   each side, so the design's 760px column collapsed to 237px and the submit
   button overhung it. Scoped to the two ported pages by body class only. */
body.pmpro-checkout .content-wrapper.container,
body.pmpro-confirmation .content-wrapper.container,
body.page-id-40 .content-wrapper.container,
body.page-id-41 .content-wrapper.container { padding-left: 0; padding-right: 0; max-width: 100%; }

body.pmpro-checkout .col-main,
body.pmpro-confirmation .col-main,
body.page-id-40 .col-main,
body.page-id-41 .col-main { padding-left: 0; padding-right: 0; }

body.pmpro-checkout .entry-content,
body.pmpro-confirmation .entry-content,
body.page-id-40 .entry-content,
body.page-id-41 .entry-content { padding-left: 0; padding-right: 0; }

body.pmpro-checkout .row,
body.pmpro-confirmation .row,
body.page-id-40 .row,
body.page-id-41 .row { margin-left: 0; margin-right: 0; }

/* The submit button must never be wider than the column it sits in. */
#pmpro_form .pmpro_form_submit input[type="submit"] { max-width: 100%; box-sizing: border-box; }

/* §70.13 The §70.9 pair override used !important to win its cascade fight, which
   also overrode the design's own narrow-width rule (checkout.css collapses
   .field-grid and .email-row to a single column at <=480). Restore that. */
@container vp (max-width: 480px) {
  #pmpro_user_fields .pmpro_form_fields > .pmpro_cols-2 {
    grid-template-columns: 1fr !important;
    grid-column: 1 / -1 !important;
  }
  #pmpro_user_fields .pmpro_form_fields > .pmpro_cols-2 ~ .pmpro_cols-2 {
    grid-column: 1 / -1 !important;
  }
}

/* 70. F-10-1 (S156, VS RUN-02) - suppress Seeko's members-filter modal where it does not belong.
   The parent theme emits a .filter-search modal ("I'm Looking for", "Type the name here",
   "Occupation or Industry", "Marital Status", "Online Status") into the footer of EVERY page,
   including the events archive and the organiser My Events workspace. It is not visible - it is
   position:fixed at 0,0 with z-index:-1 and overflow:hidden clipping its own children - so it was
   correctly recorded as dead chrome rather than a visual bug.
   It is NOT harmless, though: z-index alone does not remove it from the accessibility tree, so a
   screen-reader user browsing events meets a marital-status filter that does nothing. display:none
   takes it out of the tree as well as the paint.
   Scoped OFF the members directory, which is the one surface the filter genuinely belongs to, and
   done from the child theme rather than by editing the parent (which updates would overwrite).
   S165 (01/08/26, Rob: "yeah remove"): the emission itself is now OFF at source - the seeko-search
   plugin's form 6181 ("Main") had force_load=1 in _seeko_options, which printed the modal into
   every page's footer (class-sks-public.php force_render_modals, wp_footer:9999); that flag is now
   cleared via the plugin's own data, so nothing emits the modal anywhere. These rules stay as a
   defensive layer in case a theme/plugin update or demo re-import ever sets it again. */
body:not(.directory) .filter-search,
body:not(.directory) .filter-search-module,
body:not(.directory) .filters-members-dir {
    display: none !important;
}
/* end of 70 */

/* §72 =========================================================================
   PRE-CONTRACT SUMMARY ON CHECKOUT (S158, 29/07/26, T584 / D-147)
   The subscription facts stated at the point of purchase: price, that it renews,
   the right to cancel, the 14-day cooling-off right, and (Organiser and Venue only)
   the 5% ticket commission. Sits directly above the consent tickbox and takes the
   ported design's `.card` shell so it matches the terms card beneath it.
   ========================================================================== */
/* The shell (white, gold hairline, 16px radius, padding) comes from the ported design's
   `.card`, which this block carries alongside its own class - that is deliberate, so it
   matches the terms card directly beneath it. Do NOT re-declare background, border or
   radius here: an earlier cut set cream and 1.5px, `.card` beat both at equal specificity
   and later source order, and the override was simply dead weight. Only the things `.card`
   does not provide are set below. */
.uks-precontract__title {
    font-family: var(--font-heading, 'Montserrat', sans-serif);
    font-weight: 700;
    font-size: 15px;
    color: var(--color-navy, #031B83);
    margin: 0 0 var(--sp-sm, 8px);
}
/* NO list markers. The whole checkout is centre-aligned, so a disc-bulleted list left the
   bullets stranded at the far left of the card with the text floating in the middle,
   visibly disconnected from them. Centred lines with breathing room read correctly and
   match the page instead of fighting it. */
.uks-precontract__list {
    margin: 0;
    padding: 0;
    list-style: none;
}
.uks-precontract__list li {
    font-size: 14px;
    line-height: 1.55;
    color: var(--color-navy, #031B83);
    margin: 0 auto 10px;
    max-width: 62ch;
}
.uks-precontract__list li:last-child { margin-bottom: 0; }
.uks-precontract__list a {
    color: var(--color-navy, #031B83);
    text-decoration: underline;
}
/* S245 row 19 (Rob, the 6th of October 2026: "Again just plain text, blue text everywhere with some of it bold, looks terrible. Change the bold for gold or something. Add some colour."): the bold lead-ins
   (the price, Cancel any time, Changed your mind, the 14 days, After that) take the gold and weight the design gives the bold values of the level card on the same page
   (.uks-page-shell .level-card__body strong, color var(--color-gold), weight 700); the words around them stay navy. Measured live before: the <strong>s inherited navy (rgb(3, 27, 131)), no rule coloured them. */
.uks-precontract__list strong { color: var(--color-gold); font-weight: 700; }
/* end of §72 */

/* §71 =========================================================================
   FREE-TIER PROFILE GATE (S157, 28/07/26)
   Rob: "It should still blur other member profiles too." A Free member reads event
   details in full and browses venues and organisers freely, but another MEMBER's
   profile is blurred behind an upgrade prompt. Own profile, admins and paid tiers
   are untouched — the PHP decides that, this only paints it.
   ========================================================================== */
/* UPG-1 (S238, Rob 28/09/2026: "making normal - white panel, light cream button"): the panel is the site's
   standard card, white with a 1px gold border (D-654), so the standard cream button (D-640) reads against it.
   Was a cream panel with a 1.5px border, which made the cream button disappear into its own background.
   The vertical padding is split 28.5px / 35.5px (was 32px / 32px) so the painted margins match (LB-477): with
   32 / 32 the title's ink sat 40.25px below the top border (its line box carries the paragraph leading above
   the capitals) while the button's ring sat 33px above the bottom border, at every width, measured by ink at
   dsf 4 (results/s238/patches/UPG-1/measure). Now 36.75px and 36.5px. */
.uks-profile-upgrade-gate {
    max-width: 560px;
    margin: 0 auto var(--sp-xl, 24px);
    padding: 28.5px var(--sp-xl, 24px) 35.5px;
    background: var(--color-surface, #FFFFFF);
    border: 1.5px solid var(--color-gold, #CC9900); /* the card border of the site, unchanged by UPG-1 */
    border-radius: var(--radius-md, 16px);
    text-align: center;
    box-shadow: var(--shadow-sm, 0 1px 3px rgba(26,26,46,0.06));
}
.uks-profile-upgrade-gate__title {
    font-family: var(--font-heading, 'Montserrat', sans-serif);
    font-weight: 700;
    font-size: 19px;
    color: var(--color-navy, #031B83);
    margin: 0 0 var(--sp-sm, 8px);
}
.uks-profile-upgrade-gate__body {
    font-size: 14px;
    line-height: 1.55;
    color: var(--color-navy, #031B83);
    margin: 0 0 var(--sp-lg, 16px);
}
.uks-profile-upgrade-gate__cta { text-decoration: none; }
/* S158 29/07/26 — the same card is now also the WHOLE page on a Free member's
   /customise/ (the editor is locked to paid tiers and this is all they see), so it
   needs its own top margin there rather than sitting under a blurred grid. */
.uks-profile-upgrade-gate--standalone { margin-top: 40px; }
/* The `.btn` base layout in §42.8 is scoped to `.workspace`, and /customise/ is the one
   dashboard surface built without that wrapper (it is the full-width editor). Without
   this the CTA keeps its colours from `.btn.btn--primary` but loses its shape, padding
   and font — LB-125 exactly. Values mirror `.workspace .btn` verbatim so the button is
   pixel-identical on both surfaces; do not "improve" one without the other. UPG-1 (S238):
   except the padding, which is set by ink measurement for this label (see below). */
.uks-profile-upgrade-gate__cta.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-sm);
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 14px;
    line-height: 1;
    /* UPG-1 (S238, Rob 28/09/2026: "the fucking label isn't centred, it's low"). The mirrored 10.5px 24px put
       the painted ink of "Upgrade now" 2px below the gold ring's midpoint at 1920/1280/1024 and 1px below at
       768/600/360, and the 0.5px right: measured by ink at dsf 4 under Rule 2 overlays. The half pixel in
       10.5px was why it moved between widths: the ring snaps to a whole pixel and the glyphs snap separately,
       so a label offset of N.5px lands on N or N+1 depending on where the page puts the button. 9px on top
       makes that offset a whole number, so the label sits the same at any page position (swept at +0, 0.25,
       0.5 and 0.75px); 12px below keeps the button 39px tall; 23.5px / 24.5px moves the ink the half pixel
       left and keeps the width. Result: ink midpoint within 0.01px of the ring's on both axes at all six
       widths (results/s238/patches/UPG-1/measure). Deliberately NOT the workspace padding any more: the gate
       carries its own label and its own measurement. */
    /* 29/09/2026, the coordinator: up and down the label is centred by its CAPITAL (Rob 25/09/2026, LB-489), not by its whole
       ink, so the 9px and 12px the first build chose (whole ink, tails included) are 10.25px and 10.75px, the values the
       standard button on the no-access card carries (BTN-1); side to side the half pixel stays. */
    padding: 10.25px 24.5px 10.75px 23.5px;
    border-radius: 10px;
    /* border-WIDTH and STYLE only. This block sits AFTER §42.8 in source order at the
       same specificity, so a `border:` shorthand here would silently repaint the gold
       border-colour `.btn.btn--primary` sets to transparent. */
    border-width: 2px;
    border-style: solid;
    cursor: pointer;
    transition: all var(--duration-fast) var(--ease-out);
    white-space: nowrap;
    text-decoration: none;
    text-transform: none;
    margin: 0;
    letter-spacing: normal;
}
/* The grid stays in place so the profile still has shape and scale — it is the
   CONTENT that is withheld, not the fact the person exists. Interaction is killed
   so nothing behind the blur can be clicked or tabbed into. */
.profile-grid-public.is-upgrade-blurred {
    filter: blur(7px);
    pointer-events: none;
    user-select: none;
}
/* end of §71 */

/* ==========================================================================
   §73. THE PASSWORD-CHANGE FORM (the emailed link's landing page)
   Added S161, 30/07/26, from Rob's own testing on an Android phone.

   §70.11 already tames this control, but it is scoped to #pmpro_user_fields,
   which is the CHECKOUT form. The form served at /login/?action=rp is
   #resetpassform and was never covered, so its toggle inherited the theme's
   .pmpro_btn gold pill: measured 80x48, background rgb(204,153,0), 32px
   radius, sitting ABOVE the field (button top 514 against field top 568)
   rather than inside it. Rob: "the view password button works but it just in
   the wrong place and looks shit, wrong branding too". Both true.

   Same treatment as §70.11 and deliberately so - one idiom for one control,
   rather than a second invented style for the same thing on another page.
   ========================================================================== */

#resetpassform .pmpro_form_field-password,
#resetpassform .pmpro_form_field-password-confirm { position: relative !important; }

/* ⚠️ CORRECTED S170 (04/08/2026) - THE S161 RULE BELOW ATE THE "New Password" LABEL.
   The original collapsed this wrapper to width:0;height:0 so it could not push the field down.
   But the LABEL LIVES INSIDE THIS SAME WRAPPER:
       <div class="pmpro_form_field-password-toggle">
         <label for="pass1">New Password *</label>
         <button class="pmpro_btn-password-toggle">eye</button>
       </div>
   so collapsing the wrapper collapsed the label with it. Measured on the live page: that label
   was 0px WIDE and 86px TALL - the text wrapping one character per line inside a zero-width box -
   while the second field's label (which has no toggle, so no wrapper) measured a normal 361x29.
   Only the asterisk escaped, which is exactly what Rob saw: a bare red * under an unlabelled field.
   A fix for the toggle's POSITION silently removed a required field's label, and it survived
   because nobody re-read the page afterwards.
   The collapse was never needed: `.pmpro_form_field-password` is already `position: relative`
   above, so the absolutely-positioned button anchors to the FIELD regardless of this wrapper.
   So the wrapper goes back to being a normal full-width block that can hold its label. */
#resetpassform .pmpro_form_field-password-toggle {
  position: static !important;
  width: 100% !important;
  height: auto !important;
  overflow: visible !important;
}
/* ⚠️ S170: ANCHORED TO THE TOP, NOT THE BOTTOM, AND THE REASON MATTERS MORE THAN THE NUMBER.
   `bottom: 12px` measured the eye up from the bottom of the FIELD GROUP, and that group also holds
   `.uks-pw-help` underneath the input - which password-change-help.js grows and shrinks as the
   member types. So a bottom-anchored eye MOVES while you use the form. Measured on the live page
   before this change: the eye sat 15.4px BELOW the input's own centre (eye midY 430.8 against input
   midY 415.4). Anchoring from the top is stable, because everything above the input (the label) has
   a fixed height. Derived, not guessed: wrapper top 356.2, input top 391 and 48.8 tall, so the
   input's centre is 59.2px down; a 22px control centres on it at top: 48px. Re-measure if the label
   above ever changes height. */
#resetpassform button.pmpro_btn-password-toggle {
  position: absolute !important;
  right: 10px !important;
  bottom: auto !important;
  top: 48px !important;
  left: auto !important;
  width: 22px !important;
  height: 22px !important;
  min-width: 0 !important;
  min-height: 0 !important;
  padding: 0 !important;
  margin: 0 !important;
  background: none !important;
  border: 0 !important;
  box-shadow: none !important;
  border-radius: 0 !important;
  color: var(--color-gold) !important;
  font-size: 0 !important;
  line-height: 0 !important;
  display: flex !important;
  align-items: center;
  justify-content: center;
  z-index: 3;
}
/* R3-Q (24/09/2026, item 5): 18px matched the OLD cap-height-era login size (superseded, see
   functions.php); the reset form's eye is now the same 11.5px x-height match as login and
   checkout, stated explicitly rather than left to inherit .pmpro_icon-eye svg's global rule,
   because this page can only be reached via a genuine emailed reset key (L-356) and could not
   be measured live this session - MUST NOT send a real reset email or submit this form. The
   button's own 22x22 box, its top:48px/right:10px anchor to the INPUT's centre and its
   align-items/justify-content centring are all UNCHANGED: shrinking the icon inside an
   unmoved, unresized box is zero structural risk. What this does NOT do: reposition the eye
   to sit beside the "New Password" label with the 6px gap login and checkout now both use -
   that would mean converting .pmpro_form_field-password-toggle from S170's hard-won
   full-width block (three corrected passes, see above - the first collapse ATE the label) to
   a flex row, and that structural change needs the real page in front of someone to prove it
   still holds the label. Flagged for Rob rather than guessed. */
#resetpassform button.pmpro_btn-password-toggle svg,
#resetpassform button.pmpro_btn-password-toggle .pmpro_icon { width: 11.5px !important; height: 11.5px !important; }

/* §73.1 The submit sits DISABLED until the strength meter is satisfied, and said
   nothing about why - which is what stalled Rob ("it just paused for a while then
   stopped"). Make the disabled state look disabled, so a dead button reads as
   "not yet" rather than "broken". The explanatory text is added by
   password-change-help.js. */
/* ⚠️ REPLACED S170. The old rule made the disabled state with opacity:0.5 + grayscale(35%), and
   Rob's verdict on the result was simply that it "looks wrong" and reads grey. Washing a gold
   button out is not a brand state; it is the absence of one. The button now uses the SAME idiom as
   the dashboard buttons he pointed at (.week-nav__btn, page-polish §46.Y): cream fill, 2px gold
   border, navy text - and the press-on-click behaviour of .section-nav__item. Disabled keeps the
   brand and signals "not yet" by dropping the raise and the shadow, not by going grey. */
#resetpassform input[type="submit"],
#resetpassform #resetpass-button {
  display: block !important;
  margin: 0 auto 18px !important;          /* auto side margins = the centring Rob asked for */
  background: var(--color-cream) !important;
  border: 2px solid var(--color-gold) !important;
  color: var(--color-navy) !important;
  border-radius: 9999px !important;
  font-weight: 700 !important;
  padding: 12px 28px !important;
  line-height: 1.2 !important;             /* with equal padding, the label sits vertically centred */
  height: auto !important;
  cursor: pointer;
  box-shadow: var(--shadow-gold-hover) !important;
  transform: translateY(-1px);
  transition: transform 120ms var(--ease-out), box-shadow 120ms var(--ease-out),
              background-color 120ms var(--ease-out);
}
#resetpassform input[type="submit"]:not([disabled]):hover,
#resetpassform #resetpass-button:not([disabled]):hover {
  background: var(--color-cream-hover, var(--color-cream)) !important;
}
/* "changes on click just like in the menu buttons in the dashboard area" - the pill presses down */
#resetpassform input[type="submit"]:not([disabled]):active,
#resetpassform #resetpass-button:not([disabled]):active {
  transform: translateY(0);
  box-shadow: none !important;
  transition-duration: 50ms;
}
#resetpassform input[type="submit"][disabled],
#resetpassform #resetpass-button[disabled] {
  background: var(--color-cream) !important;
  border-color: rgba(204, 153, 0, 0.45) !important;
  color: rgba(3, 27, 131, 0.45) !important;
  cursor: not-allowed !important;
  transform: none;
  box-shadow: none !important;
  opacity: 1 !important;                   /* no wash-out */
  filter: none !important;                 /* no greyscale */
}

/* §73.3 CENTRING (S170). Rob, 04/08/2026, looking at the live page: "the text/labels/paragraph
   aren't centred either" and "the labels and the paragraph of text are all left aligned not
   centred". Measured before touching anything, per RULE 2: the CARD and the HEADING were already
   dead centre (midpoint delta 0.0px against both their container and the viewport) - it is the
   content INSIDE the card, and the submit button, that were not. */
#resetpassform,
#resetpassform .pmpro_form_field,
#resetpassform .pmpro_form_label,
#resetpassform .pmpro_form_field-password-toggle,
#resetpassform .description,
#resetpassform .indicator-hint,
#resetpassform p {
  text-align: center !important;
}
/* §73.4 THE LABEL (S170). Three faults, all measured on the live page before changing anything:
     - colour was rgb(34,34,34), a near-black that Rob read as "grey/black" against a navy brand;
     - the TEXT sat 12.9px left of centre, because the required-asterisk was being counted in the
       centring - so the more characters the asterisk block occupied, the further left the words
       were pushed. Rob: "the field labels are not centred, they are slightly off to the left - do
       not include the asterisks in the measurement";
     - the asterisk rendered a visible gap after the words, from a whitespace text node inside its
       own span. Rob: "they should be much closer to the text too".
   The label now shrink-wraps its text and is centred by the parent, and the asterisk is taken OUT
   of the flow entirely (absolute, hung off the text's right edge) so it cannot affect where the
   words sit, no matter how long the label is. */
/* ⚠️ S170, SECOND PASS. The first version keyed on `.pmpro_form_label` and reached the FIRST label
   only: measured live, pass1 was inline-block at 118.5px (correct) while pass2 was still block at
   361px, so its asterisk hung off the CARD's right edge, 98.8px from the words. Targeting the
   element (`#resetpassform label`) rather than a class it may not carry fixes both. Padding is
   zeroed too, because `left:100%` resolves to the label's PADDING edge - which is where the
   remaining 13px gap on pass1 was coming from, not from the 4px margin I had set. */
/* ⚠️ S170, THIRD PASS, AND THE REASON THE PREVIOUS TWO ONLY FIXED ONE LABEL. Traced with a
   stylesheet walk rather than guessed again: the rule below DOES match both labels and DOES win
   (`!important`, and the only competing rule is theme-static's plain `label`). The second label was
   still computing as `block` because its parent is a FLEX container - and flex BLOCKIFIES an
   inline-block child, then stretches it to the full column width, which is why its asterisk ended up
   94.8px away, hard against the card edge. `align-self: center` is the flex-correct way to say
   "shrink to your content and centre": it fixes the flex child, and is simply ignored on the first
   label, whose parent is not flex. */
#resetpassform label,
#resetpassform .pmpro_form_label {
  display: inline-block !important;
  width: auto !important;
  max-width: 100%;
  align-self: center !important;   /* the flex-item case; harmless when the parent is not flex */
  padding-left: 0 !important;
  padding-right: 0 !important;
  position: relative;
  color: var(--color-navy) !important;
}
#resetpassform label .pmpro_asterisk {
  position: absolute;
  /* `left:100%` resolves to the label's right edge, and the label's content ends with a trailing
     SPACE before this span - about 0.28em at the label's size - which is where the leftover gap was
     coming from once padding was already zeroed. Cancelling it in `em` keeps the spacing correct if
     the font size ever changes, rather than pinning a pixel value that would drift. */
  left: 100%;
  /* ⚠️ THIS MUST NOT BE EXPRESSED IN `em`, AND THAT COST THREE ATTEMPTS. This span carries
     `font-size: 0` (below) to kill the whitespace text node inside it - and `em` resolves against
     the element's OWN font-size, so ANY em value here computes to 0px. Three different em values
     all produced an identical 12px gap, which is what finally gave it away: a number that does not
     move when you change it is not being applied. Traced with a stylesheet walk, which showed the
     rule winning with `margin-left: -0.78em` while the COMPUTED margin read `0px`.
     Measured: the constant offset is 12px (the trailing space before this span plus the inline
     box's right edge), so -9px leaves the asterisk about 3px after the words. */
  margin-left: -9px;
  top: 0;
  font-size: 0;            /* kills the whitespace text node inside the span itself */
  letter-spacing: 0;
  white-space: nowrap;
}
#resetpassform label .pmpro_asterisk abbr {
  font-size: 18px;         /* back to the label's own size */
  margin-left: 3px;        /* sits just after the words */
  padding: 0;
  text-decoration: none;
  border: 0;
}

/* §73.5 BRAND SURFACES (S170). Rob, seeing the live page: "The card itself doesn't have a gold
   border. Some of the text is still black and the input field borders are also black, not gold."
   Measured before changing: the card was 1px solid rgb(232,232,232) light grey, the inputs
   rgb(119,119,119) grey (and rgb(128,189,255) blue while focused, which is a stock focus ring, not
   the brand), and the hint text rgb(34,34,34) near-black. */
/* ⚠️ THE CARD ONLY, AND NOTE HOW THIS WAS CORRECTED. My first version listed `#resetpassform` here
   too and produced TWO nested gold boxes - the card, and the form inside it - which the measurements
   happily reported as "card border: 2px gold" while the page looked wrong. Caught by opening the
   screenshot (R5b): a measurement confirms the value you asked for, it cannot tell you that you also
   applied it somewhere you did not mean to.
   ⚠️ My first correction was to ADD `#resetpassform { border: 0 !important; }` - a rule whose only
   job was to cancel a rule I had just written. Rob: *"do NOT stack fixes! Find the issue, and
   correct it by replacing, not stacking"*. He is right: the form never had a border of its own
   (measured 0px before any of this), so the fix is to take it out of the selector, not to undo it
   afterwards. A cancelling rule leaves the next person reading two rules to work out one outcome. */
.pmpro_card.pmpro_reset_password_wrap {
  border: 2px solid var(--color-gold) !important;
  border-radius: 16px !important;
}
#resetpassform input[type="password"],
#resetpassform input[type="text"] {
  border: 2px solid var(--color-gold) !important;
  border-radius: 10px !important;
  color: var(--color-navy) !important;
}
/* The focus state keeps the gold border and shows NOTHING else. The stock blue ring is killed, and
   so is the gold glow I first put here - Rob, seeing it live: "there's a bit of a glow appears on
   the field... It doesn't look right." That matches the platform's existing idiom: the dashboard
   pills (§46/§8480) deliberately suppress every native focus and tap indicator because they read as
   "the control went grey". The field's own gold border is the affordance. Removed rather than
   cancelled with a second rule. */
#resetpassform input[type="password"]:focus,
#resetpassform input[type="text"]:focus {
  border-color: var(--color-gold) !important;
  outline: none !important;
  box-shadow: none !important;
}
#resetpassform .pmpro_form_hint,
#resetpassform .description,
#resetpassform p {
  color: var(--color-navy) !important;
}

/* §73.2 The two helper lines. Live inside the form so they sit with the fields. */
#resetpassform .uks-pw-help {
  display: block;
  text-align: center;
  margin: 8px 0 0;
  font-family: var(--font-body, 'Nunito Sans', sans-serif);
  font-size: 13px;
  line-height: 1.45;
  color: rgba(3, 27, 131, 0.7);
}
/* X06 (S238): the weak-password warning line wears the brand red (--color-error #C41C1C), not #B3261E, which is
   in no brand guide. Rob: one red everywhere (S228), and the weak-password state is the brand red (26/09/26). */
#resetpassform .uks-pw-help--warn { color: var(--color-error); font-weight: 600; }
/* X06b (S238): the good-password and passwords-match line wears the brand success green (--color-success #27A644),
   not #2E7D4F, which is in no brand guide. */
#resetpassform .uks-pw-help--ok { color: var(--color-success); font-weight: 600; }

/* ============================================================================
   49. COOKIEYES CONSENT UI - BRAND PASS (S182, Rob 18/08/26: "The cookie popup
   is not on brand either and doesn't seem to be visible sometimes")
   The plugin's own markup with its dashboard-configured colours (foreign blue
   #1863DC buttons, grey text) - overridden here, !important because the plugin
   inlines its palette. Card language matches the login card: white, 2px gold
   border, 16px radius, navy copy; Accept = gold bg + navy text (D-055), the
   secondary pair = cream with gold border. The max-height guard is the
   visibility half: whatever the viewport, the banner can never overflow it. */
.cky-consent-container .cky-consent-bar {
  background: #FFFFFF !important;
  border: 2px solid #CC9900 !important;
  border-radius: 16px !important;
  box-shadow: 0 4px 24px rgba(3, 27, 131, 0.18) !important;
}
/* S219 (Rob 10/09/26): on a phone the consent panel filled the screen edge to edge. It follows the dashboard
   panels instead: the same 19px clear of each side (a 352px panel on a 390 screen, 90 percent) and lifted off
   the bottom edge by the same amount. */
@media (max-width: 600px) {
  .cky-consent-container {
    left: 19px !important;
    right: 19px !important;
    bottom: 19px !important;
    width: auto !important;
    max-width: calc(100% - 38px) !important;
    background: transparent !important; /* the card inside carries the white; the container showed a grey edge */
  }
}
.cky-consent-container {
  /* S184: was calc(100vh - 24px), which ignored the banner's own 40px desktop bottom offset -
     at an extreme short viewport (measured live at 900x180) the capped card poked 16px above the
     viewport top. 64px = the 40px offset + 24px breathing, so the promise in this section's
     header ("whatever the viewport") actually holds; at normal heights the cap never engages. */
  max-height: calc(100vh - 64px) !important;
  overflow: auto !important;
}
.cky-consent-container .cky-title,
.cky-modal .cky-title {
  font-family: "Montserrat", sans-serif !important;
  color: #031B83 !important;
  font-weight: 700 !important;
}
.cky-consent-container p,
.cky-consent-container .cky-notice-des,
.cky-consent-container .cky-notice-des p,
.cky-modal p, .cky-modal .cky-preference-content-wrapper,
.cky-modal .cky-accordion-header-des {
  font-family: "Nunito Sans", sans-serif !important;
  color: #031B83 !important;
}
.cky-consent-container a, .cky-modal a { color: #CC9900 !important; }
/* S182 (Rob's second ruling, same day): ALL THREE buttons share the cream base; the state
   colour arrives on interaction - Accept goes to the greens, Reject to the reds, Customise to
   the slightly darker cream. */
/* F-070 (S234, 21/09/2026): the panel's close button and its five category toggles were left out
   of this list, so they kept CookieYes's own 9px corners against D-508's 10px. They are added to
   the selector rather than given a rule of their own; the declarations below are unchanged, and
   both controls are transparent-background chrome, so only the radius is visible on them.
   S245 row 104: the category toggles (.cky-accordion-btn) are taken OUT of this list again. Listed here they were painted as the cream pills with a 2px gold ring that Rob rejected
   ("I'm not sure why they're pills anyway"); they are the centred, gold-underlined titles of the section 49.1 block below. */
.cky-consent-container .cky-btn,
.cky-modal .cky-btn,
.cky-modal .cky-btn-preferences,
.cky-modal .cky-show-desc-btn,
.cky-modal .cky-btn-close {
  background: #FFFBE6 !important;
  border: 2px solid #CC9900 !important;
  color: #031B83 !important;
  border-radius: 10px !important;
  font-family: "Montserrat", sans-serif !important;
  font-weight: 700 !important;
  /* S244 rows 102, 103 and 112: the fill, the lift and its shadow move together at the platform's button speed (the .btn-option timing, 43.1), not Seeko's 0.4s transform. */
  transition: background-color 120ms ease-out, box-shadow 120ms ease-out, transform 120ms ease-out;
}
.cky-consent-container .cky-btn-accept:hover, .cky-consent-container .cky-btn-accept:focus, .cky-consent-container .cky-btn-accept:active,
.cky-modal .cky-btn-accept:hover, .cky-modal .cky-btn-accept:focus, .cky-modal .cky-btn-accept:active {
  background: #EAF4EC !important;
  border-color: #2F7D4F !important;
  color: #2F6B47 !important;
  outline: none !important;
}
.cky-consent-container .cky-btn-reject:hover, .cky-consent-container .cky-btn-reject:focus, .cky-consent-container .cky-btn-reject:active,
.cky-modal .cky-btn-reject:hover, .cky-modal .cky-btn-reject:focus, .cky-modal .cky-btn-reject:active {
  background: #FBEAE9 !important;
  border-color: #B3261E !important;
  color: #B3261E !important;
}
/* S244 rows 102 and 103 (Rob, the 8th of October 2026: "you hover over customize and it goes this weird slightly grey colour, what's that all about? It should just be the darker
   green like any of the other buttons" (the words as dictated; the S182 ruling above says Customise goes to "the slightly darker cream", and no other cream button on the site goes
   green), and "the same kind of thing for the save my preferences button"). MEASURED LIVE with a real pointer: Customise hovered painted #F3E9C8 (rgb(243,233,200), the
   beige-grey) and Save My Preferences painted nothing at all (it kept its rest cream: no hover rule named it), and BOTH were also faded by CookieYes's own
   `.cky-btn:hover { opacity: 0.8 }`. The site's darker cream is --color-cream-hover (#FFF5CC), the pair every other cream button uses (.btn--primary, .btn-dashboard,
   .btn-menu--active), so that is the value, and Save My Preferences joins this rule rather than getting its own. */
.cky-consent-container .cky-btn-customize:hover, .cky-consent-container .cky-btn-customize:focus, .cky-consent-container .cky-btn-customize:active,
.cky-modal .cky-btn-customize:hover, .cky-modal .cky-btn-customize:focus, .cky-modal .cky-btn-customize:active,
.cky-modal .cky-btn-preferences:hover, .cky-modal .cky-btn-preferences:focus, .cky-modal .cky-btn-preferences:active {
  background: var(--color-cream-hover) !important;
}
/* S244 rows 102, 103 and 112 (Rob: "the same pop effect that the other buttons have", "all the buttons that do something negative ... don't pop when you hover"): all four of the
   banner's and panel's buttons (Customise, Reject All, Save My Preferences, Accept All) take the canonical hover lift and shadow (.btn-option, 43.1) on top of the colours above
   (Accept's greens and Reject's reds are exactly as they were: Rob called them correct), a real pointer only and not while held, with the plugin's 0.8 fade taken off so the colour
   a button hovers to is the colour it paints. Accept's `box-shadow: none !important` that stood in its rule above is gone for the same reason: it would have been the only
   button of the four with no lift. The ring stays 2px #CC9900 (the base rule's !important) on Customise and Save My Preferences, and the greens and reds restate theirs.
   S245 row 130 (Rob, the 9th of October 2026: "the drop shadows are so completely different between these buttons ... check which ones actually correct and make sure they all have
   them"; of the banner's Customise and the panel's Save My Preferences: "It's darker cream, massive drop shadow, doesn't suit the other two buttons that it sits with"). THE ONE SHADOW.
   MEASURED live, a real pointer on each of the six buttons: at rest NONE of them had a shadow, and hovered each took the two-layer lift shadow from .btn-option (0 4px 4px + 0 8px 18px),
   so the one under the pointer stood out beside two that were flat: exactly Rob's picture. READ OFF the signed-off dashboard buttons as a member (Prev and Next, Randomise, Profile and
   Customise, the calendar arrows; the same as the Messages .btn--primary and .btn--danger Rob passed), the site's shadow is `0 4px 12px rgba(0,0,0,.16)` (--shadow-gold-hover, D-640 and
   D-655): the same at rest and hovered, none when held, with the cream going --color-cream at rest to --color-cream-hover hovered and held. All four buttons of the banner and of the
   panel now carry it at rest, keep it when hovered, and lose it when held (the colours each hovers to, and the lift, are exactly as above). The six selectors name the button by both
   its classes so that they count 0,3,0: the plugin writes `.cky-notice-btn-wrapper .cky-btn { box-shadow: none }` (0,2,0) in its own inline stylesheet, which loads after this one, and
   a tie at 0,2,0 is decided by that order (measured: the first version of this rule, `.cky-consent-container .cky-btn`, left every banner button at `none`). */
.cky-consent-container .cky-btn.cky-btn-customize,
.cky-consent-container .cky-btn.cky-btn-reject,
.cky-consent-container .cky-btn.cky-btn-accept,
.cky-modal .cky-btn.cky-btn-reject,
.cky-modal .cky-btn.cky-btn-preferences,
.cky-modal .cky-btn.cky-btn-accept {
  box-shadow: var(--shadow-gold-hover);
}
.cky-consent-container .cky-btn:hover,
.cky-modal .cky-btn:hover { opacity: 1; }
@media (hover: hover) {
.cky-consent-container .cky-btn:hover:not(:active),
.cky-modal .cky-btn:hover:not(:active) {
  transform: translateY(-1px);
}
}
.cky-consent-container .cky-btn:active,
.cky-modal .cky-btn:active {
  box-shadow: none;
}
.cky-modal, .cky-modal .cky-preference-center {
  background: #FFFFFF !important;
  border: 2px solid #CC9900 !important;
  border-radius: 16px !important;
}
/* The floating revisit-consent button stays brand navy. */
.cky-btn-revisit-wrapper { background: #031B83 !important; }
/* F9b (S240, the 5th of October 2026): the on and off switch beside a cookie category. CookieYes
   draws it as an appearance-none checkbox, and Seeko's theme-static.min.css gives every checkbox
   opacity 0 (its custom-checkbox pattern); CookieYes sets no opacity of its own, so its switch sat in the
   panel at full size but invisible once the site's real cookies were listed (D-747). Opacity is the only
   declaration restored: the plugin's own size, colours and knob are left exactly as it draws them. */
.cky-modal .cky-switch input[type="checkbox"] { opacity: 1; }
/* S244 row 103 (Rob, the 8th of October 2026: "T toggle buttons go blue when toggled on, they should be green"). CookieYes paints a switched-on category in its own blue and
   writes it twice: in its stylesheet, `.cky-switch input[type="checkbox"]:checked { background: rgb(24, 99, 220) }`, and again as an INLINE style on the input the moment it is
   turned on (`style="background-color: rgb(24, 99, 220);"`, read off the Functional switch live after turning it on). An inline style outranks every rule that is not !important,
   which is why this section already says "!important because the plugin inlines its palette", and why a green written without it measured blue. The white knob and the 44 x 24
   size are the plugin's and stay. The green is the platform's confirmed-on green, the one the site's own toggle turns to when it is on (.ev-toggle--on .ev-toggle__track,
   §69.10: --color-success, #27A644). */
.cky-modal .cky-switch input[type="checkbox"]:checked { background-color: var(--color-success, #27A644) !important; }
/* S244 row 103 (Rob: "The main body of text at the top should be centered as with the title"). Measured live, both the panel's title ("Customise Consent Preferences") and the two
   paragraphs under it were left-aligned (text-align: left, inherited from the panel), so the title is centred here as well: Rob reads it as centred, and the site centres its
   titles (BRAND_GUIDE panels, S219 "all normal text centred"). The title takes the header's free width and, from 441px up, the close button's own 24px on its left so its centre
   is the panel's centre (the close button is the header's only other child); below that the title fills the width beside the button and does not wrap. The category lists
   under the paragraphs (the technical rows) are not touched. */
.cky-modal .cky-preference-header .cky-preference-title { flex: 1; text-align: center; }
@media (min-width: 441px) {
.cky-modal .cky-preference-header .cky-preference-title { padding-left: 24px; }
}
.cky-modal .cky-preference-content-wrapper { text-align: center; }
/* 49.1 THE CATEGORY TITLES AND THE EXPANDED COOKIE DETAIL (S245 row 104; Rob, the 8th of October 2026: "If you click the down arrow for one of the cookies, it comes up with a panel that
   hasn't been styled and it has black text, and weird colored backgrounds, no go border, etc. For all these cookies and the expanded view, I don't mind that it's left aligned just because
   of the technical nature of the information. The title pills don't have any padding before and after the first and last letters. But I'm not sure why they're pills anyway. In fact, yeah,
   just redo this the same style as like anywhere else where the titles would have a gold underline and everything is centered."). MEASURED live on the panel with Functional expanded:
     - each category title was a cream pill with a 2px gold ring and NO padding (the plugin's `.cky-accordion-btn` has padding 0, and the base rule above painted it as a button);
     - the detail panel (.cky-audit-table) carried an INLINE style written by the plugin (color #212121, background-color #f4f4f4, border-color #ebebeb) and Seeko's reset gave it a 3px solid
       border, so it was a grey box with a 3px grey edge, a 6px radius and black labels (Cookie, Duration, Description) over navy values.
   THE VALUES ARE COPIED, NOT INVENTED. The title is the site's title (copied from event-page.css 11.14 .host-register__title, and from the S231 main page titles in this file, "the shadow
   and the gold underline spacer, like on the event pages", which Rob ruled for every title): navy, centred, the gold rule 2px under the words and hugging them, 8px of room above it, the
   same text-shadow (0 4px 6px rgba(3,27,131,.18), 0 2px 4px rgba(3,27,131,.12)); its size, weight and face stay the title's own (16px, Montserrat 700). The detail panel is the site's
   panel (the host register card's, event-page.css 11.14, and the Messages panels): white, a gold border (1px, as Rob asked), the card radius (--radius-md, 16px, D090), navy text; the gold
   rules between one cookie and the next are the plugin's own `border-bottom: 1px solid` with `border-bottom-color: inherit`, which now inherits the panel's gold. The technical rows stay
   left aligned, as Rob allowed. The prose line under each title is centred like the title and like the panel's own opening text (row 103).
   !important throughout this block for the reason the section's header gives: the plugin writes its palette inline and again in its own stylesheet, and every state of the title is stated
   (Seeko's `button:hover` would paint it #f0f0f0 with #191919 text and no border). The header becomes a three column grid with the title in the middle one and the switch (or "Always
   Active") in the last, so the title is centred on the PANEL whatever the width of what sits beside it. The plugin's chevron takes 22px on the header's left (15px from 425px down:
   `.cky-accordion-chevron { margin-right }`), so the header and the prose line under it, which start after it, were centred 11px (7.5px) right of the panel and of the detail panel
   below (MEASURED: title midpoint 651.0, panel midpoint 640.0, first version of this block); both take the chevron's width back with a negative left margin, which costs nothing
   because that part of the row holds only the chevron's own arrow, drawn in the first 14px at the very top. */
.cky-modal .cky-accordion-item { --c2-chev: 22px; }
@media (max-width: 425px) {
.cky-modal .cky-accordion-item { --c2-chev: 15px; }
}
.cky-modal .cky-accordion-item .cky-accordion-header {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: start;
  margin-left: calc(-1 * var(--c2-chev));
}
.cky-modal .cky-accordion-item .cky-accordion-header .cky-accordion-btn { grid-column: 2; }
.cky-modal .cky-accordion-item .cky-accordion-header .cky-switch,
.cky-modal .cky-accordion-item .cky-accordion-header .cky-always-active { grid-column: 3; justify-self: end; }
.cky-modal .cky-accordion-item .cky-accordion-header .cky-accordion-btn,
.cky-modal .cky-accordion-item .cky-accordion-header .cky-accordion-btn:hover,
.cky-modal .cky-accordion-item .cky-accordion-header .cky-accordion-btn:focus,
.cky-modal .cky-accordion-item .cky-accordion-header .cky-accordion-btn:active {
  background: transparent !important;
  border: 0 !important;
  border-bottom: 2px solid var(--color-gold) !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  color: var(--color-navy) !important;
  font-family: "Montserrat", sans-serif !important;
  font-weight: 700 !important;
  margin: 0 !important;
  padding: 0 0 8px !important;
  text-align: center;
  text-shadow: 0 4px 6px rgba(3, 27, 131, 0.18), 0 2px 4px rgba(3, 27, 131, 0.12);
}
.cky-modal .cky-accordion-header-des { text-align: center; margin-left: calc(-1 * var(--c2-chev, 22px)); }
.cky-modal .cky-accordion .cky-accordion-chevron i { color: var(--color-navy) !important; }
.cky-modal .cky-audit-table {
  background: #FFFFFF !important;
  border: 1px solid var(--color-gold) !important;
  border-radius: var(--radius-md, 16px) !important;
  color: var(--color-navy) !important;
}
/* The plugin takes the detail panel's RIGHT gutter away from 576px down (`.cky-accordion-active .cky-accordion-body { padding-right: 0 }`) and gives it 15px each side again from 425px
   down, so between 426 and 576 the panel sat 22px in on the left and flush on the right, 11px off the centred title above it (MEASURED at 440: panel midpoint 231 against 220). The
   gutter is given back there, so the panel is the same width each side at every width. */
@media (min-width: 426px) and (max-width: 576px) {
.cky-modal .cky-accordion.cky-accordion-active .cky-accordion-body { padding-right: 22px; }
}
/* end of 49 */

/* ============================================================================
   50. KEYBOARD FOCUS OUTLINES (S190, 24/08/26)

   Rob: "Give blue outlines for focus."

   WHY IT WAS NEEDED. Seeko's parent theme carries `button:focus { box-shadow:
   rgba(0,0,0,.5) 0 0 0 0 }` and `.btn:focus { outline: 0 }`, so a member moving
   through the platform with the Tab key had nothing at all telling them where
   they were. It surfaced while fixing the dashboard calendar's green ring,
   which that same zero-spread shadow was silently erasing.

   🔴 WHY THERE IS NO !important HERE, AND IT MUST STAY THAT WAY. This file
   already carries nineteen `outline: none !important` rules and several are
   DELIBERATE, not oversights: line 5887 says so in its own comment, "S76 Rob
   pt2: remove browser focus-ring (blue halo that persists on click)" on the
   header menu toggle; the .section-nav pills style their own focus; the panic
   shield uses a WHITE outline because it sits on dark red. A blanket
   !important rule would reinstate the exact halo Rob had removed and recolour
   a safety control. Without !important, every one of those keeps winning
   automatically and only controls that currently show NOTHING gain an outline,
   which is the whole of the complaint.

   THE .btn BLOCK IS NOT DUPLICATION. The parent's `.btn:focus { outline: 0 }`
   is 0-2-0 and outranks a bare `button:focus-visible` at 0-1-1, so without it
   the site's main buttons gained nothing. These match its specificity and this
   stylesheet loads after it, so they win with no !important needed.

   :focus-visible, NOT :focus, so the outline appears for keyboard and
   assistive navigation and does NOT linger on every mouse click - which is the
   behaviour Rob had removed in S76. If he wants it on click too, swap each
   :focus-visible below for :focus.

   DRIVEN BEFORE DEPLOY (tools/vs4_t029_focus_outline_trial.js): the calendar
   day cells, the month arrows and the Randomise button all went from
   "outline: none" to the blue outline, the sidenav links were already blue,
   and the section-nav pills were driven on a real public profile and STAYED
   at outline:none. The header toggle could not be reached to drive; its own
   rules are !important on the element and on both focus states, so this rule
   cannot beat it by any specificity - reasoned, and recorded as reasoned.
   ============================================================================ */
/* 🔴 THE `body ` PREFIX IS LOAD-BEARING, DO NOT TIDY IT AWAY. The parent theme-static.min.css
   loads AFTER this file, and it carries `button:focus { outline: ... }` at 0-1-1 and
   `.btn:focus { outline: 0 }` at 0-2-0. Without the prefix these selectors merely TIE on
   specificity, and a tie is decided by document order, which the parent wins - the first deploy
   landed `outline-offset: 2px` and no outline at all, which is exactly what that looks like.
   `body ` adds one element to each, so every rule here now OUTRANKS its parent counterpart on
   merit rather than by !important, which is what keeps the deliberate exceptions intact. */
html[data-nav="kbd"] body a:focus-visible,
html[data-nav="kbd"] body button:focus-visible,
html[data-nav="kbd"] body input:focus-visible,
html[data-nav="kbd"] body select:focus-visible,
html[data-nav="kbd"] body textarea:focus-visible,
html[data-nav="kbd"] body summary:focus-visible,
html[data-nav="kbd"] body [tabindex]:focus-visible,
html[data-nav="kbd"] body .btn:focus-visible,
html[data-nav="kbd"] body input[type="submit"]:focus-visible,
html[data-nav="kbd"] body input[type="button"]:focus-visible,
html[data-nav="kbd"] body input[type="reset"]:focus-visible {
  outline: 2px solid #031B83;
  outline-offset: 2px;
}

/* S190 (Rob: "all three circles are different sizes"): on the CALENDAR CELLS ONLY, the focus ring
   is pulled onto the border box so it measures the same 30x28 circle as the today and going marks.
   The sitewide 2px / 2px offset above is unchanged for every other control, where sitting just
   outside the control is the right shape. A negative offset equal to the width puts the outline's
   outer edge exactly on the border box edge. */
html[data-nav="kbd"] body .cal__cell:focus-visible {
  outline: 1.5px solid #031B83;
  outline-offset: -1.5px;
}
/* end of 50 */


/* ============================================================================
   48. SECTION: Keyboard focus indicator (S199, 31/08/26, Rob's ruling)
   ============================================================================

   THE PROBLEM, as found in S190 and settled today. Seeko's own stylesheet carries
   `button:focus { box-shadow: rgba(0,0,0,.5) 0 0 0 0 }` - a shadow with ZERO spread, so it
   paints nothing. `box-shadow` is a single property, so that empty rule REPLACES any focus ring
   the child theme puts on a button. The highlight was not missing by accident; it was being
   erased. It is the same rule that was silently eating the dashboard calendar's "going" ring,
   which was fixed locally in S190 while this, the sitewide half, was left for Rob.

   HIS RULING, 31/08/26: put a proper brand ring on every button, in gold, to match the gold
   glow the form fields already have.

   WHY `outline` AND NOT `box-shadow`. Using box-shadow would mean fighting Seeko's rule in the
   parent theme, which cannot be edited. `outline` is a different property that nothing on this
   site sets on a button - every `outline: none` in this stylesheet is on an input, a textarea
   or a select, all of which already carry their own gold box-shadow ring. So this needs no
   specificity fight and clobbers nothing.

   WHY `:focus-visible` AND NOT `:focus`. `:focus-visible` fires for keyboard navigation and
   not for a mouse click, which is exactly the split wanted: a keyboard user always sees where
   they are, a mouse user never gets a ring flashing on every button they press.

   WHY THE RING SITS OUTSIDE THE BUTTON. `outline-offset: 2px` puts it clear of the button's own
   fill, so it reads on gold buttons, navy buttons, cream buttons and white ones alike. A ring
   drawn inside the fill would vanish on the gold ones, which is the trap the 0.25-alpha input
   convention would have walked into if it had been copied literally onto buttons.
   ============================================================================ */

/* 48.1 The ring itself.
   FIRST ATTEMPT WAS WRONG AND THE TEST CAUGHT IT. It listed `button` plus a hand-picked set of
   classes, and tabbing across eight real pages found the ring on 1 of 32 focused controls. The
   reason: almost every "button" on this platform is an ANCHOR styled as one - `a.card-btn` on
   pricing, `a.header-login-btn` in the top bar, `a.preview-nav-btn`, `a.directory-apply-button`
   - so a `button`-scoped rule missed nearly all of them. What the other 31 were showing was
   Chrome's OWN default focus ring, which takes its colour from the element and therefore paints
   navy on a navy pricing card: present in the computed style, invisible to the eye.
   So the rule covers everything a keyboard can land on instead of a guessed list. */
html[data-nav="kbd"] a:focus-visible,
html[data-nav="kbd"] button:focus-visible,
html[data-nav="kbd"] [role="button"]:focus-visible,
html[data-nav="kbd"] [tabindex]:focus-visible,
html[data-nav="kbd"] summary:focus-visible,
html[data-nav="kbd"] input[type="submit"]:focus-visible,
html[data-nav="kbd"] input[type="button"]:focus-visible,
html[data-nav="kbd"] input[type="checkbox"]:focus-visible,
html[data-nav="kbd"] input[type="radio"]:focus-visible {
    outline: 2px solid #CC9900 !important;
    outline-offset: 2px !important;
}
/* end of 48.1 */

/* 48.2 Inputs, textareas and selects are deliberately NOT included. They already carry the gold
   box-shadow ring this site has used since S79 (`box-shadow: 0 0 0 2px rgba(204,153,0,.25)`),
   and every `outline: none` in this file belongs to one of them. Adding a second ring would
   double it up on exactly the controls that were already correct. */
/* end of 48.2 */

/* end of 48. SECTION: Keyboard focus indicator */


/* ============================================================
   52. S215 KEYBOARD FOCUS: the section-nav pills (T-S204-006)
   D-425 (Rob, 31/08/26) rules a GOLD keyboard ring site-wide, and it works:
   real Tab presses across three pages found 13 of 14, 23 of 27 and 23 of 24
   focused controls carrying it. The section-nav pills were the exception,
   because 8984 and 9015 set `outline: none !important` on their :focus state,
   which outranks the site-wide :focus-visible rule.
   :focus-visible ONLY, so a mouse click still never flashes a ring, which is
   the S76 removal Rob asked for and D-425 preserved.
   The customise widget rail stays excluded: D-425 is explicit that this is a
   conscious product decision of Rob's, not an oversight. Do not extend it there.
   ============================================================ */
html[data-nav="kbd"] #buddypress .section-nav__item:focus-visible,
html[data-nav="kbd"] .section-nav__item:focus-visible {
    outline: 2px solid var(--color-gold) !important;
    outline-offset: 2px !important;
}

/* ============================================================
   53. S215 KEYBOARD FOCUS: form fields (T-S204-006 family, D-425, BRAND_GUIDE 13)
   D-425 left inputs, selects and textareas out of its site-wide gold ring on the
   stated ground that they "already carry their own gold box-shadow ring".
   MEASURED LIVE 08/09/2026 on /contact/: the glow is exactly
   rgba(0,0,0,0) 0 0 0 0, and the border is ALREADY gold at rest, so focusing a
   field changed nothing a keyboard user could see. The exemption rested on
   something that is not true, so the ring the guide specifies is applied here.
   :focus-visible ONLY, so a mouse click never flashes a ring (Rob, S76).
   EXCLUDED, deliberately: the customise widget rail, which D-425 rules a
   conscious product decision of Rob's, and the D043-locked editor chrome.
   ============================================================ */
html[data-nav="kbd"] body input:not([type=hidden]):not([type=submit]):not([type=button]):focus-visible,
html[data-nav="kbd"] body select:focus-visible,
html[data-nav="kbd"] body textarea:focus-visible {
    outline: 2px solid var(--color-gold) !important;
    outline-offset: 2px !important;
}
body .profile-sidebar *:focus-visible,
body .widget-rail *:focus-visible {
    outline: none !important;
}

/* ============================================================
   54. S215 MOBILE: legal tables stack instead of running off the screen
   MEASURED at 360px on 08/09/2026: /cookie-policy/ rendered 479px of content
   and /privacy-policy/ 437px from their five-column tables, and because html and
   body both hide horizontal overflow that content was CLIPPED, not scrollable.
   Rob, 08/09/2026: "if a table does not work out on a screen width that is too
   small, like on mobile, then you vertically stack in sections one then two then
   three etc." So below 768 each ROW becomes its own block and each cell sits on
   its own line, in the order the columns run. The header row is hidden at that
   width only, because stacked it would read as five stray words above the first
   row; it returns in full above 768. Nothing is deleted (RULE 13).
   ============================================================ */
@media (max-width: 767px) {
    .entry-content table,
    .entry-content tbody,
    .entry-content tr,
    .entry-content td {
        display: block;
        width: 100%;
        max-width: 100%;
        box-sizing: border-box;
    }
    .entry-content thead {
        display: none;
    }
    .entry-content tr {
        border-top: 2px solid var(--color-gold, #CC9900);
        /* Rob 08/09/2026: it read as stretched because the cells ran edge to edge.
           16px of breathing space each side, so the block sits inside the screen. */
        padding: 12px 16px 14px;
        margin: 0;
    }
    .entry-content td {
        border: 0;
        padding: 3px 0;
        text-align: left;
        /* Rob 08/09/2026: the stacked cells were rendering grey. Navy, like every other
           body line on the platform. */
        color: var(--color-navy, #031B83);
    }
    .entry-content tr td:first-child {
        font-weight: 700;
        color: var(--color-navy, #031B83);
        padding-bottom: 6px;
    }
}

/* =========================================================================
   S219 (VC 06, 10/09/26): two missing rules
   ========================================================================= */
/* T-S216-021 (D-494): the Upcoming / Past tab row on a venue- or organiser-filtered /events/ page.
   The pills are .btn-menu (43.3); this is only the row around them, which sat hard left. */
.events-when-tabs {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 10px;
    margin: 0 0 18px;
}
/* Rob 10/09/26: "All the cards need to be uniform and fixed." A blog post card fills its column, so a
   card whose title fits one line is as tall as its neighbours. */
[class*="col-"]:has(> article.post-card) {
    display: flex;
    flex-direction: column;
}
[class*="col-"] > article.post-card {
    flex: 1 1 auto;
}
/* Rob 10/09/26: the ONLINE patch globe sat high, and icons follow the sidenav ratio: icon ink is 2.6
   times the height of the capital letters beside it (19px ink against 7.3px capitals). The globe's
   ink is 77 percent of its box, so a 28px box gives 21.5px of ink against the patch's 8.3px capitals. */
/* D-509 (Rob 10/09/26, "Right, use it everywhere"): the No screens phone on the same ratio. Its ink is
   85 percent of its box: beside the 18px event page label (13px capitals) a 40px box gives 34px of ink;
   beside the 11px card patch capitals (8px) a 24px box gives 21px. Negative margins keep the line height. */
.event-no-screens-pill-icon svg {
    width: 40px;
    height: 40px;
    vertical-align: middle;
    margin: -8px 2px -8px 0;
}
.event-card .event-no-screens-pill-icon svg {
    width: 24px;
    height: 24px;
    margin: -6px 2px -4px 0;
}
/* The card patch is navy, and the phone is drawn in navy, so on the card its body turns cream like the
   patch lettering; the gold strike stays gold. */
/* S219 (Rob 10/09/26, "the label itself is too high now"): the letters and the globe shared one text line, so
   ONLINE sat 1.38px above the patch centre by its painted ink. A centred row puts both on the centre (0.38px). */
.event-card-badge-online {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    line-height: 1 !important;
}
.event-card-badge-online svg.uks-glyph--globe {
    width: 20px;
    height: 20px;
    vertical-align: middle;
    margin: 0 4px 0 0;
}
/* Rob 10/09/26 on item 120: the Preferences ring at the right-hand end of every Report answer, gold at
   rest, green with a green dot when chosen, the same 22px ring and 10px dot as .pf-opt__radio. */
.uks-report-reason {
    position: relative;
}
.uks-report-reason::after {
    content: "";
    position: absolute;
    right: 16px;
    top: 50%;
    width: 22px;
    height: 22px;
    box-sizing: border-box;
    border: 2px solid #CC9900;
    border-radius: 50%;
    transform: translateY(-50%);
    pointer-events: none;
}
.uks-report-reason:has(input:checked)::after {
    border-color: #2F7D4F;
    background: radial-gradient(circle, #2F7D4F 0 5px, transparent 5.5px);
}
/* Rob 10/09/26 on item 116: "Only the label itself, the text, should ever be centred, the tick just adds on
   to the end. That again should be a global property of all buttons." A button whose label carries an icon
   puts the icon INSIDE the label span and positions it absolutely, so the label's box is the words alone:
   the button centres the words, and the icon hangs off the label's own end (or start). */
.btn-icon-fix-label {
    position: relative;
    display: inline-block;
}
.btn-icon-fix-icon--trail,
.btn-icon-fix-icon--lead {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    white-space: nowrap;
}
.btn-icon-fix-icon--trail {
    left: 100%;
    margin-left: 6px;
}
.btn-icon-fix-icon--lead {
    right: 100%;
    margin-right: 6px;
}
/* S231 18/09/26 (triage item 19). The trailing tick on Interested and Reported was the keyboard
   character U+2713, the same one Rob had replaced on the pricing cards in S230 because it renders
   differently on every system. It is now the brand tick drawing, stroked in currentColor so it
   takes the selection green on Interested and the button colour everywhere else. Rob 10/09/26 on
   item 116 still governs the placement: "Only the label itself, the text, should ever be centred,
   the tick just adds on to the end." */
/* S231 18/09/26 (triage item 20c), Rob: "The ticks are still below center. They are aligned with
   the bottom of the text. They should be centered with the centre of the text." The trail span is
   centred on the LABEL BOX, which includes descender space, so a cap-only word like Interested has
   its cap band higher than that box centre. MEASURED by decoding an 8x screenshot and comparing the
   tick's ink centre with the text's cap-band ink centre: the tick sat 0.375px low. */
.btn-icon-fix-tick {
    display: block;
    transform: translateY(-0.375px);
}
/* D-506 as amended by Rob 10/09/26: "show the "never been customised" label and make sure the label is centered
   and put it on a nice gold-bordered card - it can be white background with a drop shadow". Markup from
   profile-system.php (grid3): div.profile-grid__not-customised-card > p.profile-grid__not-customised, placed
   by the switcher inline. Three wordings: a Free account, the owner (with a link to Customise), a visitor. */
.profile-grid-public > .profile-grid__not-customised-card {
    background: #FFFFFF;
    border: 2px solid #CC9900;
    border-radius: 16px;
    box-shadow: var(--shadow-md, 0 4px 12px rgba(26, 26, 46, 0.12));
    padding: 24px;
    text-align: center;
    max-width: 640px;
    width: 100%;
    margin-inline: auto;
    box-sizing: border-box;
}
.profile-grid__not-customised-card > .profile-grid__not-customised {
    margin: 0;
    color: #031B83;
    font-size: 1rem;
    line-height: 1.5;
    text-align: center;
}
.profile-grid__not-customised-link {
    color: #CC9900;
    font-weight: 700;
    text-decoration: underline;
}
/* S231 18/09/26 (triage item 22), Rob: "If the profile is blank, then just show the warning on its
   own card, don't show the blank profile... drop the outer outline when the grid is empty." At 1280
   the empty grid still drew its own gold outline and white card around the note, so the note read
   as a gold box inside a gold box. */
.profile-grid.profile-grid--not-customised {
    min-height: 0;
    /* the switcher sizes the card's row span from the notice before this card styling applies, so the span
       came out 28px short and the card ran over the Report and Block buttons; auto rows fit the card */
    grid-auto-rows: auto !important;
}
.profile-public-wrapper--business > #pub-profile {
    margin-top: 24px !important;
}
.profile-public-wrapper--business .profile-public-report-footer {
    margin-top: 36px !important;
}
/* T-S218-024 (S218, 10/09/2026, Rob: "there shouldn't be anything on the image"). The event card's
   three badges, plus the no-screens pill, now sit in a row of their own at the top of the card body,
   directly under the image and above the title. The theme badge and the format badge keep their look
   from the unscoped .event-card-badge rules; the two PILLS do not, because their only card rules
   (33.1 and 35.1) are scoped to .event-card-image, so the same values are given here without the
   absolute positioning. */
.event-card__badges {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 6px;
    margin-bottom: 8px;
}
.event-card__badges .event-card-badge {
    position: static !important;
    top: auto !important;
    left: auto !important;
    right: auto !important;
    transform: none !important;
    margin-top: 0 !important;
    white-space: nowrap;
}
.event-card__badges .event-age-pill {
    position: static;
    background: #FFFBE6;
    color: #031B83;
    border: 2px solid #CC9900;
    border-radius: 9999px;
    padding: 4px 12px;
    font-family: Montserrat, sans-serif;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.event-card__badges .event-no-screens-pill {
    position: static;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background: #031B83;
    color: #FFFBE6;
    border: 2px solid #CC9900;
    border-radius: 9999px;
    padding: 4px 10px 4px 8px;
    font-family: Montserrat, sans-serif;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
/* Rob 10/09/26: "Make these extra kind of category labels like no screens and over 18s, gold, let's see what that
   looks like." The labels under the event description (18+, No screens) were bare text; they are the brand
   category pill: gold ground, navy lettering, fully rounded. The phone icon takes navy to match. */
.event-badges {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 8px;
}
.event-badges .event-age-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--color-cream, #FFFBE6);
    color: #031B83;
    border: 2px solid #CC9900;
    border-radius: 9999px;
    /* S222 14/09/26 (T-S219-065), Rob: the hero 18+ label "is a little high" in its pill. MEASURED
       with the canvas cap-height method: the label's cap centre sat 1.445px ABOVE the pill's own
       centre, because Montserrat's caps sit high in the em box and the padding was symmetric. The
       total stays 8px so the pill's height does not move (28.89px before and after); the content
       simply starts 1.445px lower. Same idiom as the card pills' 5.3/2.7. */
    /* S222, second pass, 14/09/26. Rob, on a live card: "the tag showing the ages, the text is too
       low. Check that again, should be global for all tags." The first pass centred the label by the
       FONT's cap metric; measuring the PAINTED ink at dpr 8 showed that left it 0.58px low. This is
       the ink figure: ink midpoint on the pill's midpoint, total padding still 8px so the pill's
       height does not move. */
    /* The text snaps to whole device pixels at this size: padding-top anywhere from about 4.4 to
       5.5 paints the label in the SAME place (ink 0.58px low), and 4.29 drops it one pixel (ink
       0.45px high). There is no value that lands it dead on, so this takes the smaller error, and
       the high side, because low is what Rob could see. */
    padding: 4.29px 14px 3.71px;
    font-family: Montserrat, sans-serif;
    font-size: 13px;
    font-weight: 700;
    line-height: 1.3;
}
/* D-651 (S235 FIXER-SHADOWS-3, 24/09/26): the gold rest shadow, scoped to the clickable category
   pill only (event-system.php:14660, always an <a>). The base .event-badges .event-age-pill rule
   above is shared with the non-clickable <span class="event-age-pill"> age-group pill (e.g. "18+",
   event_system_age_group_pill_html()), so the shadow does not go on that shared rule. */
.event-badges a.event-age-pill.event-category-pill {
    box-shadow: var(--shadow-gold-hover);
}
.event-badges a.event-age-pill.event-category-pill:active {
    background: var(--color-cream-hover, #FFF5CC);
    box-shadow: none;
}
/* Rob 10/09/26: "Make them the light cream except for the no screens that's now going to be the reds". */
.event-badges .event-no-screens-pill,
.event-card__badges .event-no-screens-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--color-error-bg, rgba(196, 28, 28, 0.06));
    color: #C41C1C;
    border: 2px solid #C41C1C;
    border-radius: 9999px;
    padding: 4px 14px;
    font-family: Montserrat, sans-serif;
    font-size: 13px;
    font-weight: 700;
    line-height: 1.3;
}
.event-card__badges .event-no-screens-pill {
    font-size: 11px;
    padding: 4px 10px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.event-badges .event-no-screens-pill-icon svg [stroke="#031B83"],
.event-card__badges .event-no-screens-pill-icon svg [stroke="#031B83"],
.event-badges .event-no-screens-pill-icon svg [stroke="#FFFBE6"],
.event-card__badges .event-no-screens-pill-icon svg [stroke="#FFFBE6"] { stroke: #C41C1C; }
.event-badges .event-no-screens-pill-icon svg [fill="#031B83"],
.event-card__badges .event-no-screens-pill-icon svg [fill="#031B83"],
.event-badges .event-no-screens-pill-icon svg [fill="#FFFBE6"],
.event-card__badges .event-no-screens-pill-icon svg [fill="#FFFBE6"] { fill: #C41C1C; }
.event-badges .event-no-screens-pill-icon svg [stroke="#CC9900"],
.event-card__badges .event-no-screens-pill-icon svg [stroke="#CC9900"] { stroke: #C41C1C; } /* the strike too, so the phone is one colour */

.event-badges .event-no-screens-pill-icon svg {
    width: 20px;
    height: 20px;
    margin: -2px 0;
}


/* ============================================================================
   52. THE DIRECTORY CARD - ONE CARD FOR EVENTS, VENUES AND ORGANISERS
   S220 VC 07, 14/09/2026. Rob signed the design off today: "they look way better
   ... we keep all three of those now."

   ONE SKELETON, THREE TYPES. 310px wide, one fixed height per type, and the only
   thing that changes between an event, a venue and an organiser is the words in
   it. D-519: no Verified tick anywhere on it.

   THE RULES THIS CARD IS BUILT ON, so nobody has to rediscover them:
   - Nothing is printed on the cover image, not even the type pill. The pills sit
     on the SHOULDERS, the row below the cover, either side of the sigil. The red
     No screens pill is ALWAYS the right shoulder (Rob: "it just looks better on
     the right").
   - The cover is the account's own profile banner, the same picture their profile
     shows, exactly as the sigil already works, until members can edit their cards.
     An event uses its own image. With neither, the brand panel shows.
   - ONE 16px rhythm owns every gap. No child sets its own vertical margin.
   - The fact panel is an inset block with a navy border, navy dividers and navy
     text, and it carries three facts that can never be missing, so no card can
     collapse for want of data.
   - MEASURED, not eyeballed (results/s220/cards/, overlay_*.png): the button
     labels were 0.50px low, the pill labels 0.75px high, and the fact dividers
     were being taken out of the cells, leaving two of the three 0.5px narrow.
     All three are corrected below and the overlays prove 0.00px.
   - The buttons take .btn-option as their base class, per BRAND_GUIDE 9.7. The
     modifier here sets only the cream fill, D-508's 10px corners and the padding
     that makes the pair equal width.
   ========================================================================== */
.uks-card {
  /* local names so the rules below read as they were designed; every value is a
     project token, nothing is a new colour */
  --navy: var(--color-navy);
  --gold: var(--color-gold);
  --cream: #FFFBE6;                 /* LB-023 brand cream, the canonical button fill */
  --white: var(--color-surface);
  --navy75: var(--color-text-secondary);
  --head: var(--font-heading);
  --body: var(--font-body);
  --step: var(--sp-lg);             /* 16px, the one rhythm */
}
.uks-card{width:310px;background:var(--white);border:1.5px solid var(--gold);border-radius:16px;
  box-shadow:0 2px 4px rgba(26,26,46,.04),0 4px 12px rgba(26,26,46,.08);
  overflow:hidden;display:flex;flex-direction:column}
/* S231 18/09/26, Rob: "from the bottom of the sigil down to the top of the title, there's quite
   a bit of space... we can extend the image down by maybe another twenty pixels." 164 to 184. */
.uks-card__cover{height:184px;position:relative;border-bottom:1.5px solid var(--gold);
  background:linear-gradient(135deg,#031B83 0%,#0a2ca0 100%)}
.uks-card__cover--gold{background:linear-gradient(135deg,#CC9900 0%,#FFD700 100%)}
.uks-card__cover--photo{background:linear-gradient(135deg,#1d3f6e,#4a6b8a)}
.uks-card__cover--photo{background:linear-gradient(150deg,#2b4a5e,#6f97ab 60%,#c3d6dd)}
.uks-card__sigil{position:absolute;left:50%;top:calc(100% + 15px);bottom:auto;transform:translateX(-50%);z-index:2;
  width:78px;height:78px;border-radius:50%;border:3px solid var(--gold);
  background:var(--navy);display:flex;align-items:center;justify-content:center;
  box-shadow:0 3px 12px rgba(0,0,0,.25);overflow:hidden}
.uks-card__sigil svg{width:38px;height:38px}
.uks-card__sigil--photo{background:linear-gradient(145deg,#6b7fa8,#8fa3c4)}
/* Item 33 (Rob, 24/09/2026, from his phone): "above the name there's a massive gap before the sigil, so the name has
   to be moved up and the space the description goes into needs to be made higher to fill the space." MEASURED on the
   live venue, organiser, event and member cards at 360 and 1280: the shoulder row already ends 16px below the sigil and
   this padding added a second 16px, so the name block sat 32px below the sigil against the 16px step every other gap in
   the card uses. The top padding goes, the name block sits one 16px step below the sigil, and the 16px it frees goes to
   the description block (.uks-card__meta, 52.3). */
.uks-card__body{padding:var(--step);padding-top:0;display:flex;flex-direction:column;gap:var(--step);align-items:center;text-align:center}
/* Approved 20/09/26: the sigil sits fully below the cover and the two shoulder-pill
   groups share its row, with 15px vertical and horizontal clearance. R3-32b 25/09/26, Rob
   (screenshot: "the shoulder pills are below centre, most of them are too low"): MEASURED
   on ink at dpr 2 on /organisers/, /venues/, /events/, /members/ - every single pill's cap-
   to-baseline midline sat 0.922px below the sigil's own midline, on every card type, both
   shoulders. The cause is not the pill (its own text is already centred in its own box to
   -0.078px): .uks-card__cover's absolute-positioning containing block is its PADDING edge,
   183px tall (184px border-box minus its 1px bottom border), so the sigil's top:calc(100%
   + 15px) lands 14px below the row's top, not 15 - the row's own centre sits 1px lower than
   the sigil's. Splitting the 30px vertical padding 14/16 instead of 15/15 moves the row's
   centre up by exactly that 1px, closing every measured shoulder to -0.078px. */
.uks-card__shoulders{display:grid;grid-template-columns:minmax(0,1fr) 78px minmax(0,1fr);align-items:center;
  width:100%;column-gap:15px;padding:14px 12px 16px;min-height:108px}
.uks-card__shoulder{display:flex;flex-wrap:wrap;gap:4px;align-content:center}
.uks-card__shoulder--left{justify-content:flex-end}
.uks-card__shoulder--right{justify-content:flex-start}
.uks-card__name{font-family:var(--head);font-weight:700;font-size:17px;line-height:1.25;color:var(--navy)}
.uks-card__meta{font-size:12px;line-height:1.4;color:var(--navy75)}
.c__pills{display:flex;flex-wrap:wrap;gap:6px;justify-content:center;align-content:flex-start}
.c__pills--two{min-height:48px}
.uks-card__pill{font-family:var(--head);font-weight:700;font-size:8.5px;letter-spacing:.03em;text-transform:uppercase;
   /* S220: measured live, the capitals sat 0.797px HIGH in the pill; this moves them down by that
      much without changing the pill's height. Rob: the pills and the icon are all low. */
   /* S224 15/09/26, item 223, REVERTED ON ROB'S WORD. He compared the two and chose the earlier
   one: "the original before was actually better and you say it's 0.58 pixel low, but it
   definitely looks better than when you've raised it, and I think it's because the hyphen
   between the two numbers is actually low and not on the center of the numbers, and to fix it
   you've raised the whole thing, numbers and hyphen. So, I think the issue here is the hyphen
   is too low. So, revert it to the position it was in before, but just move the hyphen up."
   Back to VC 07's S220 value, taken from commit c76db4ee, not guessed. THE HYPHEN HALF IS NOT
   DONE HERE: it is one character inside a text node, so nothing in CSS can reach it. It needs
   the age range's hyphen wrapped in a span by the card renderer first; the hand-off is on the
   task row for the next code lane. He has accepted the whole-pixel painting limit as a V2
   problem: "we don't have time, and I don't care enough to do the same thing on all these
   elements so just do as I say by reverting and then raising the hyphen only." */
   /* MEM-1 (S238, the 28th of September 2026). Rob: "The fucking character badges are STILL NOT
   FUCKING CENTRED! ... Stop fucking measuring things by code and then confidently telling me
   they're fucking fixed when they're not!" MEASURED ON THE PAINTED INK, dpr 4, every width of the
   verification set (results/s238/patches/MEM-1/): the 5.3px/2.7px padding left every pill's
   capitals 0.875px LOW against the pill's own border at 768 and wider (0.5 to 1.14px low at dpr 1
   to 3), while the drawn icon beside them sat on the centre, so word and icon were a pixel apart;
   at 600 and below the icon, sitting on the text baseline, made the character pill taller than
   the tier pill and dropped its word 1.375px; and on a phone, where the icon wraps above the word,
   the icon sat 1.5px left of centre because the 3px gap was its own margin. The cause is that the
   pill centred a text LINE and a baseline-aligned glyph, and Montserrat Bold's capitals do not sit
   on the centre of their own line box (1.125px high of it at 8.5px, measured).
   The pill is now a centring flex box with two children: the icon, and the label in its own
   .uks-card__pill-label (uks_card_pill_html(), event-system.php 10.1a.3f, and
   business-card-popup.js). The label's layout box is trimmed to the band its capitals occupy
   (see .uks-card__pill-label below), so centring the boxes centres the INK, side by side and
   stacked. min-height is exactly the old height (one line plus the old 8px of padding and the
   2px of border), so no pill changes size; the padding only matters when the content is taller
   than that (the stacked icon on a phone, or a two-line label). The 3px icon gap is a
   column-gap, which is never applied at the end of a line, so a stacked icon is truly centred. */
   text-indent:.015em;display:inline-flex;align-items:center;align-content:center;justify-content:center;column-gap:3px;row-gap:2px;min-height:calc(1lh + 10px);padding:3px 7px;border-radius:9999px;border:1px solid var(--gold);background:var(--cream);color:var(--navy);white-space:nowrap}
/* D-651 (S235 FIXER-SHADOWS-3, 24/09/26): the gold rest shadow, scoped to the <a> variant only.
   .uks-card__pill is shared with a non-clickable <span> (uks_card_pill_html() in event-system.php
   prints a <span> for a static shoulder pill, e.g. a member's archetype badge or "No screens",
   whenever the caller gives the pill no url) so a bare .uks-card__pill rule would shadow those too. */
a.uks-card__pill{box-shadow:var(--shadow-gold-hover)}
a.uks-card__pill:active{background:var(--color-cream-hover);box-shadow:none}
.uks-card__pill--alert{border-color:#C41C1C;color:#C41C1C;background:rgba(196,28,28,.06)}
/* S231 18/09/26 (triage item 27), Rob: at 360 "the character badge is cut off by the card edge".
   MEASURED at 360: the shoulders grid is 1fr 96px 1fr inside a 300px card, so each shoulder is
   about 90px, and CULTURE VULTURE needs more than that on one line with white-space:nowrap, so it
   ran straight off the card. On a phone the badge is allowed to wrap inside its own shoulder and is
   capped at the shoulder width; the shoulders already carry min-height 52px, so a second line does
   not change the card's height and D-597 still holds. Desktop keeps one line. */
@media (max-width: 600px) {
  .uks-card__shoulder .uks-card__pill {
    white-space: normal;
    /* S231 18/09/26, second pass. Rob: "the labels for the character badges run off the pills
       themselves". MEASURED at 360: the pill had collapsed to 40.0px while its text line was
       41.9px, so the words painted outside their own pill. min-content stops the pill shrinking
       below its longest word; max-width still keeps it inside the shoulder. At 390 the overflow
       was 2.9px and at 412, which is the width of Rob's own phone, it already fitted - which is
       why it looked right to him and wrong to me. */
    min-width: min-content;
    max-width: 100%;
    text-align: center;
    line-height: 1.15;
    /* MEM-1: when the icon and the word do not fit side by side inside the shoulder, the icon
       moves onto its own row above the word (as it did before), now centred on both axes. */
    flex-wrap: wrap;
  }
}
/* MEM-1b (S238, Rob, the 29th of September 2026). On a screen narrower than 400px the member card is 246px wide (measured at 360:
   shoulders of 56px either side of the 78px ring, a 15px gap and 12px of side padding, so 67px a side to the card's edge), and the
   right badge ran past the card edge. His rulings: "Tighten them up ... but keep the inner gaps by the sigils the same for every
   badge so there's uniformity"; the badge TEXT stays the size it was (a smaller text was tried and he had it put back: "they
   looked better then"); the names that still do not fit are being renamed by him.
   The gap between a badge and the ring is 4px on both sides of every card, and the side padding is 4px: 79px a side. */
@media (max-width: 399px) {
  .uks-card__shoulders { column-gap: 4px; padding-left: 4px; padding-right: 4px; }
}
/* MEM-1c (S238, Rob, the 29th of September 2026; D-719, D-720, D-722). THE MEMBER CARD, ONE LAYOUT AT EVERY WIDTH.
   His rulings, in order: every member card shows the member's three chosen badges; "in descending order of size I meant
   smallest first, largest at the bottom. Always."; "Put the membership tier back under the name like it was originally";
   "the top and bottom of the badges should align with the top and bottom of the sigil, and the tier should be way closer,
   like 10 pixels below the name"; the phone card passed ("Yes, phone card is right"); and for wide screens "just copy the
   mobile version". The order is set in PHP (event-system.php 10.1a.6b2); this block is the placing.
   - ROW 149 (S245, Rob, the 9th of October 2026): "Let's actually have two columns with their centers marked and then the
     centre of the sigil lies on the centre line of the left column and the centre of the character badges lies on the center
     line of the right column." The card is cut into two halves along its painted outer edge: the LEFT column holds the ring,
     centred on that column's centre line (a quarter of the card's width in from its left edge); the RIGHT column holds the
     badges, centred on that column's centre line (three quarters across). Both lines are worked from the cover's width (the
     card less its border): the ring's left is 25% less half the ring (39px) less 0.625px; the badge column starts at 50% plus
     1.5px. The card's border is declared 1.5px and paints 1px on a 1x screen, so the ring's 0.625px is half of 1.25px, the
     middle of the two widths, and the column's 1.5px is the declared width. Measured on the painted ink (member-card lane
     folder, 09/10/2026, three cards, 1920 to 360): on a real 8x screen the ring is within 0.19px and the badge stack within
     0.06px of their lines; in the 1x instrument both sit on the whole pixel nearest the line (a 78px ring cannot sit on a half
     pixel line there). This REPLACES the S238 placing (the ring 10px from the left edge, the badges centred in the room beside
     it), which left the ring 27px and the badge stack 33px left of their column centre lines at 1280.
   - The column is as tall as the ring (78px: 14px above it as before, 15px below). A badge is 20px tall and the gap
     between badges is 9px, so three badges are exactly 78px: the first one's top is on the ring's top and the last one's
     bottom on the ring's bottom, and every badge starts on a whole pixel. One badge or two sit centred on the ring with
     the same 9px gap.
   - A badge here is always one line (the longest name, Adventurous Eater, measured 117px without a glyph and 130px with
     one; the narrowest card, 246px at 360, has a right column 120.5px wide: row 149).
   - The name and the tier badge share one block, 59px tall on every card (D-597: the rows are fixed). A one-line name
     sits where it sat before (centred in the 42.5px its own box had) and the tier badge starts 39px down the block,
     about 10px under the name. A two-line name fills its 42.5px, the tier badge follows it at the same distance, and
     the block's height does not change: the badge uses the empty room above the Active line, which is one line in a box
     three lines tall. */
.uks-card--member .uks-card__sigil{left:calc(25% - 39.625px);transform:none}
.uks-card--member .uks-card__shoulders{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:9px;
  padding:14px 0 15px calc(50% + 1.5px);min-height:0;height:107px;box-sizing:border-box}
.uks-card--member .uks-card__shoulder{display:contents}
.uks-card--member .uks-card__shoulders > div:not(.uks-card__shoulder){display:none}
.uks-card--member .uks-card__shoulder .uks-card__pill,
.uks-card--member .uks-card__tier-row .uks-card__pill{white-space:nowrap;flex-wrap:nowrap;min-width:0;max-width:none;line-height:1.15;min-height:20px}
.uks-card--member .uks-card__nameblock{display:flex;flex-direction:column;align-items:center;width:100%;height:59px}
.uks-card--member .uks-card__nameblock::before{content:"";flex:0 1 10.625px}
.uks-card--member .uks-card__nameblock .uks-card__name{flex:none;height:auto;max-height:42.5px;max-width:100%}
.uks-card--member .uks-card__tier-row{flex:none;display:flex;justify-content:center;margin-top:7.125px;min-height:20px}
/* S220: a pill may carry its own glyph. The member card's right shoulder is the member's
   character (Socialiser, Connector and so on) and takes the drawn mark with it. */
.uks-card__pill svg{flex:none;width:10px;height:10px}
/* MEM-1: the label's box, trimmed round its capitals. Measured at 8.5px Montserrat Bold: the
   capitals (5.95px tall) sit 1.125px above the centre of their own line box. These two margins
   make the label's box an 8.95px band centred on the capitals, so a label beside an icon or alone
   centres by its painted capitals. The band's height (the capitals plus 1.5px each side) matters
   only when the icon is stacked above the word on a phone: it is the value that centres the
   stacked pair by ink for all six character icons at once, whose artwork stops 0.7 to 2.3px short
   of the top of its own 10px box (worst case 0.4px either way). Both margins are written against
   1lh, so they hold at the desktop line height, at the 1.15 the phone rule below sets, and on a
   label that wraps to two lines (the top margin trims the first line, the bottom the last). */
.uks-card__pill-label{margin-top:calc((11.2px - 1lh) / 2);margin-bottom:calc((6.7px - 1lh) / 2)}
/* MEM-1: the one character icon whose artwork is not drawn on its own centre. The Socialiser
   group spans 4.7 to 23.1 of its 24-unit box, so its ink sits 0.79px below the middle of the 10px
   icon, and beside the word it read low; this lifts the drawing by exactly that. A transform
   moves the paint without moving the box, so nothing else in the pill shifts. The other five
   sit within 0.23px of their box's centre. */
.uks-card__pill .uks-icon-character--socialiser{transform:translateY(-0.79px)}
/* S227 (VC cloud 01, 15/09/26), item 223, the hyphen half of Rob's ruling. He kept the S220
   pill position and asked for the hyphen alone to come up: "the issue here is the hyphen is
   too low ... revert it to the position it was in before, but just move the hyphen up."
   MEASURED ON INK at dpr 8 on a live 16-17 pill: the digits' ink centres on row 112.50 and the
   hyphen's on 117.50, so the hyphen is 0.625px low. It is raised by exactly that.
   position:relative with top:-0.625px was tried FIRST and produced a byte-identical capture:
   the layout box moved and the paint did not, which is the whole-pixel painting limit. A
   transform is composited instead of laid out, so it keeps the sub-pixel, and it was confirmed
   to repaint at dpr 1, 2, 3 and 8. vertical-align was also tried and moves the DIGITS, which
   is the opposite of what he asked for. inline-block is what makes the element transformable;
   it rounds the hyphen's advance width, so the pill grows by 0.125px and nothing else. */
.uks-card__age-sep{display:inline-block;transform:translateY(-0.625px)}
.uks-card__facts{display:flex;width:100%;background:var(--cream);border:1.5px solid var(--navy);border-radius:10px;overflow:hidden}
.uks-card__fact{flex:1 1 0;min-width:0;position:relative;
  /* S220, second pass. Rob: "the postcode and area label seem to be too high compared to the
     others." Measured on the VISIBLE ink band (the top of the value's capitals down to the
     label's baseline, ignoring the descender on 2y): 11.0px of space above it and 13.0px
     below, so the pair sat 1px high in the cell. 11px of bottom padding becomes 9px, which
     moves the pair down exactly 1px and balances it. */
  padding:9px 4px 9px;text-align:center}
/* the divider is drawn ON the boundary rather than taken out of the cell, so all three cells are
   the same width and their contents sit on the cell's true centre */
.uks-card__fact + .uks-card__fact::before{content:'';position:absolute;left:-0.75px;top:0;bottom:0;width:1.5px;background:var(--navy)}
.uks-card__fact-value{font-family:var(--head);font-weight:700;font-size:15px;color:var(--navy);line-height:1.1}
.uks-card__fact-label{font-family:var(--head);font-weight:600;font-size:9px;letter-spacing:.06em;text-transform:uppercase;color:var(--navy75);margin-top:3px;
  /* letter-spacing adds a trailing gap after the last letter, which the centring counts as ink and
     drags the word left by half a step. This puts it back. */
  text-indent:.03em}
.uks-card__foot{padding:var(--step);padding-top:0;display:flex;flex-direction:column;gap:var(--step);align-items:center}
/* S231 18/09/26 (triage item 23, D-597): the stand-in controls on your own member card. They hold
   the action row open so every card is the same height, and they are invisible to sight, to the
   pointer and to a screen reader. */
.uks-card__btn--placeholder{visibility:hidden;pointer-events:none}
/* 52.1 THE CARD'S BUTTONS ARE THE SITE'S BUTTONS, not a fourth family.
   The mockup drew them cream with 15px side padding. Two things about the live
   platform say otherwise and they win:
   (1) BRAND_GUIDE 9.7 - pick one of the three canonical base classes and ADD it.
       .btn-option is the public-site default, so every card button carries it and
       this modifier adds nothing it already owns (shape, font, border, padding).
   (2) Rob, 10/09/2026, on button padding: "Don't change the padding yet. Leave
       that as a post-launch task." .btn-option's own 7px 12px therefore stands,
       and when that post-launch pass moves the whole family to about 15px, these
       cards move with it for free instead of being a second source of truth.
   The cream fill is ALSO left off deliberately: cream is .btn-option's HOVER
   state everywhere on the site, so a permanently cream card button would read as
   stuck mid-hover. Flagged to Rob rather than decided quietly.
   All this modifier does is make the pair equal width. */
.uks-card__btn--quiet{ /* reserved: the Report button's hook, no declarations yet */ }
/* S224 14/09/26, Rob's second-half responses, item 225: "reduce the width of the buttons now so
   that the longest button has 15 pixel [padding] either end and then make the other button the
   same width. Make sure this is the same on every card type." This SUPERSEDES his earlier
   answer the same evening ("Shrink to the word, centred"), which left Favourite 88.17 and
   Report 72.11. A grid whose track is 1fr inside a fit-content box sizes BOTH columns to the
   widest button, so the longer label gets exactly its 15px and the shorter one matches its
   neighbour, and the box still centres in the card. */
.uks-card__actions{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:10px;justify-content:center;width:fit-content;margin-left:auto;margin-right:auto}
/* S222 14/09/26: the pair must be the same height and on the same line. On a member card the
   Favourite control is an <a> and Report is a <button>, and both carry align-self:center from
   the button family, so the shorter one floated 4.8px lower and 9.6px shorter (measured at 768:
   40.0 against 30.4). align-items:stretch cannot fix it while align-self is center, so both take
   the card button's own height. */
/* S224 14/09/26, Rob by AskUserQuestion: "Shrink to the word, centred". Measured before on
   /members/ as a member: the actions row was 276 wide at 1280 and each button took an equal
   share at 133, so the 56.17px label floated with 38.41 and 38.42 either side; at 360 the
   column gave each button 168 and the same label floated with 55.91 and 55.92. flex:1 1 0 was
   what stretched them. flex:0 0 auto lets each button hug its own label, and the container's
   justify-content:center centres the pair. The 15px side padding below is then the real gap. */
.uks-card__actions .uks-card__btn{min-width:0;min-height:40px;align-items:center}
/* 52.2 THE TALL CARD IS 310px WIDE, SO EVERY GRID IT LIVES IN NEEDS ROOM FOR 310.
   S220 VC 07, 14/09/2026, from the S218 cd1 measurement (results/s218/cd1/PROOF_geometry.json).
   The period grids and both directories are already flex-centred at 30.0.6 / 30.0.6a and measured
   0px overlap. These two were still display:grid with 280px columns and every rule scoped to
   .event-card, so a 310px card overlapped its neighbour by 6.0px at 768, 1024, 1280 and 1920, and
   at 360 the Similar events card stuck 61px past its panel. */
.events-page-wrapper .events-featured-scroll,
.events-featured-scroll,
.events-page-wrapper .events-grid.events-grid-small,
.events-grid.events-grid-small {
    display: flex !important;
    flex-wrap: wrap !important;
    justify-content: center !important;
    gap: 16px !important; /* S230 17/09/2026, Rob: "Gap to 16px" so three 310px cards fit the 965px the page gives at 1280. */
    grid-template-columns: none !important;
    width: auto !important;
    max-width: 100% !important;
}
.uks-card { max-width: 100%; }
/* 52.3 LIVE CORRECTIONS, S220, the hour the markup went live.
   (a) The title and the address line are LINKS, and the platform's link colour is gold, so every
       card title came out gold instead of navy. An anchor inside a card takes the card's own
       typography; it is a link, not a coloured word.
   (b) ROB'S FIXED-HEIGHT RULE, his words on the venue grid: "each row needs to be fixed. So the
       content of any other row doesn't affect its position. It should all be fixed. They should all
       be the exact same size because we can't account for what information the users are gonna
       give." A title runs to one line or two and an address to one, two or three, so both blocks
       are given the height of their longest allowed form with the content centred inside it. Every
       card of a type is then the same height whatever the data does. */
.uks-card__name a {
    color: inherit;
    text-decoration: none;
}
.uks-card__meta a {
    color: var(--color-gold);   /* R3-33 (Rob 26/09): "the venue link should be gold like everywhere else"; the title above stays navy; hover stays the dark gold below */
    text-decoration: none;
}
/* S231 18/09/26, Rob: "on the event cards, when you hover over the title, because it's a link it
   goes gold, like the dark gold. That should be the case on all of these cards. The venue cards,
   member cards, event cards. Whenever you hover over something that's a link, should go gold."
   `color: inherit` above fixed the rest state and took the hover with it, so a card link had no
   hover at all. One rule for the one card, so every card type behaves the same. */
.uks-card__name a:hover,
.uks-card__name a:focus-visible,
.uks-card__meta a:hover,
.uks-card__meta a:focus-visible,
.uks-card__fact-value a:hover,
.uks-card__fact-value a:focus-visible {
    color: var(--color-gold-dark, #80641D);
    text-decoration: none;
}
.uks-card__name {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 42.5px;
    overflow: hidden;
}
.uks-card__meta {
    display: flex;
    align-items: center;
    justify-content: center;
    /* S222 14/09/26, VC 08: the member card's line is the text "Active" followed by
       <span class="activity">3 minutes ago</span>. A flex container makes the bare text an
       anonymous item and drops the space between them, so every member card read "Active3
       minutes ago". 0.26em is the width of a word space in Montserrat at this size, so the line
       reads exactly as it would have. Only the member card's line has two parts (72 of 72 on
       /members/; the event, venue and organiser cards carry a single part), so nothing else moves. */
    column-gap: 0.26em;
    /* Item 33 (Rob, 24/09/2026): "the space the description goes into needs to be made higher to fill the space".
       Two lines (33.6px) become three: 3 x 12px x 1.4 = 50.4px, the 16px the name block gave up above (.uks-card__body)
       plus 0.8px so the third line is whole. Every card type shares this block, so events, venues, organisers and
       members keep identical rows (D-511). The short description limit was measured against these three lines at 360
       (event-system.php 10.1a.3h). */
    height: 50.4px;
    overflow: hidden;
}
/* 52.4 ROB, 14/09/2026, two on the live card.
   (a) "put the location whether it's online or a physical location in gold, it'll look a bit nicer".
   (b) "the view event button is far too wide. Make it so that it reaches half the width of the left
       and right information panel above, so it has the date and the price halfway through each of
       those should be the left and right side of the view event button." The fact panel is three
       equal cells, so the centre of the first to the centre of the third is exactly two thirds of
       its width, whatever the card is. 66.667% and centred, not a pixel value, so it holds at every
       breakpoint and on every card type. */
/* S231 18/09/26, REVERSED ON ROB'S WORD. The gold above was his own 14/09 instruction; on
   18/09 he read it on a real card and changed his mind: "now I think the description being gold
   is a bit too difficult to read. I think it's gonna have to go back to being blue." The base
   rule's navy at 75 per cent is what it goes back to, so this override is gone rather than
   restated with a different value. */
.uks-card__actions {
    /* S220, second pass. The two thirds below was measured for a card carrying ONE button, where
       Rob wanted it to span from the centre of the first fact cell to the centre of the last. A
       card with TWO buttons inside two thirds leaves each of them 87px, which is what made the
       labels touch the edges on the venue cards. So two thirds applies only when there is one
       button; a pair takes the full width of the card.
       S224 14/09/26, item 225 SUPERSEDES that last clause: a pair no longer takes the full
       width. The row is a fit-content grid whose two 1fr tracks both size to the WIDER
       button, so the longer label gets exactly 15px each side and the shorter button
       matches it, which is what Rob asked for. The auto margins below still centre the
       row, and the lone-button rule that follows keeps his two-thirds span untouched. */
    width: fit-content;
    margin-left: auto;
    margin-right: auto;
}
.uks-card__actions:has(> :only-child) {
    width: 66.667%;
}
/* Rob: "There isn't enough padding. You need to add 15 pixel padding between the edges of the
   buttons and the text label, Then make sure the report button is the same width as well so it all
   looks symmetrical." The pair is already equal width (flex 1 1 0), so this is the padding half.
   !important because .btn-option's own block is armoured with it against the parent theme;
   BRAND_GUIDE 9.7 point 4 allows the scoped bump and leaves the base rule alone. */
.uks-card__actions .uks-card__btn {
    padding-left: 15px !important;
    padding-right: 15px !important;
}
/* And when a card button carries a trailing tick (Show Interest becomes Interested), the tick hangs
   off the end of the WORD, which is what keeps the word centred, so the button needs the tick's own
   room on BOTH sides or it overlaps the border. Same fix as the Reported button: 15px of label
   padding plus 15px for the tick.
   S227 item 116, Rob: "the tick is sticking out the right-hand side of the button". The event
   page's own Interested control has the identical markup and the identical fault (measured
   3.2px of tick outside the border at 360 and 3.3px at 1280), so it joins this rule rather
   than getting a second one of its own. */
.uks-card__actions .uks-card__btn:has(.btn-icon-fix-icon--trail),
.event-page .wishlist-button:has(.btn-icon-fix-icon--trail) {
    padding-left: 30px !important;
    padding-right: 30px !important;
}
/* 52.5 THE VENUE AND ORGANISER SEARCH PANEL, S220 14/09/2026, T-S218-056.
   Rob at 1280: "look at this layout, it's ridiculous. Look how wide that panel is underneath
   venues with the search options, look how wide they all are. They do not need to be that wide
   at all." MEASURED: the panel was 868.5px because the control row inside it genuinely needs
   713.3px and the section adds its own padding. 760px is as narrow as it goes before those
   controls wrap onto a second line, so that is where it is set, scoped to the two directory
   pages by their own ids so /events/ is untouched. If he wants it narrower still, the controls
   themselves have to shrink, and that is his call, not a number I should invent. */
body.page-id-6898 .events-page-wrapper .events-filter-section,
body.page-id-6944 .events-page-wrapper .events-filter-section,
body.page-id-6898 .events-page-wrapper .events-filter-form,
body.page-id-6944 .events-page-wrapper .events-filter-form {
    /* 30.5 sets width 90% and max-width 1296px with !important, because that bar is shared with
       /events/ where it is right. It cannot simply be edited without changing /events/ too, so
       this narrows it for the two DIRECTORY pages only, by their own page ids, and needs the same
       !important to reach past it. BRAND_GUIDE 9.7 point 4 is the licence for that: bump the
       selector, leave the base rule alone.
       MEASURED, so the number is not a guess: the controls inside this panel were ALREADY stacked
       one per line before this change (four lines, each control full width), at 868.5px wide. So
       the width was pure empty space either side of them and nothing wraps differently at 700px. */
    width: 100% !important;
    max-width: 700px !important;
    margin-left: auto !important;
    margin-right: auto !important;
}
/* 52.5a THE SEARCH CONTROLS INSIDE THAT PANEL, S220 14/09/2026.
   Rob: "why would I let the search input fields are ridiculously wide? Far too wide. They're like
   three times wider than they should be. Reduce them by 35% width." He also said to leave the panel
   itself alone now, so this narrows only the controls. They were 628px each, one per line; 65 percent
   of that is 408.2px, and they stay centred on the panel. */
/* S230 17/09/2026. Rob's 65% was measured on a DESKTOP panel: his words were about controls
   that were 628px each and "three times wider than they should be". At 360 the same row is only
   248px, so 65% of it is 161.2px and all three controls are squeezed: the dropdown label "All
   Event Types" needs 103px and had 101px, so it painted "All Event Ty..." with an ellipsis. The
   cap is therefore held at the widths it was asked for and released below 601px, where the three
   controls take the full width of the row together and stay matched with each other, exactly as
   they already do on the events page. Narrowing the rule, not stacking a counter-rule on it. */
/* F-065 (S233, 21/09/2026). Rob at 1280 on /organisers/ after a far-postcode search: the type
   dropdown truncated to "All ...", the Search button sat beside it off-grid, and Show anywhere
   rendered as a full-width box. ONE rule caused all three, and it is this one.
   MEASURED on the live page. The control row is a centred wrapping flex row while it is the form's
   only row (32.8.2 reaches it as :last-child), which is the venues layout Rob calls correct: every
   control 65% of the 628px row, one per line, the button centred beneath. The moment a location
   search adds the "Showing organisers around" row, the control row stops being :last-child, drops
   back to 32.3's four-column grid, and this rule then measures 65% of a 148px CELL instead of the
   row: the dropdown became 96.19px with 28px of chevron padding each side, leaving 40px for a label
   needing 103px. The button, auto-width in the next cell, landed 80.01px off the row centre. Both
   are answered by spanning the row, which is what 32.3 already does for .events-search-input and
   what this block's own 65% widths have always assumed.
   The same rule also reached the SECOND row, because that row carries .events-filter-row too, and
   stretched the Show anywhere pill to 408.19px: the full-width box. Its own comment is about "the
   search input fields", never the note line, so the selector is narrowed to the control row. The
   pill then returns to its natural 109.8px, which is what it has always been below 601px.
   After: dropdown 408.19px and unclipped, button 98.7px at 0.01px off centre, both exactly the
   venues geometry; /venues/ itself measured unchanged at 1280. */
@media (min-width: 601px) {
body.page-id-6898 .events-filter-row:not(.events-filter-row-secondary) > *,

body.page-id-6944 .events-filter-row:not(.events-filter-row-secondary) > * {

    width: 65% !important;

    max-width: 65% !important;

    margin-left: auto !important;

    margin-right: auto !important;

    grid-column: 1 / -1 !important;

}
}
body.page-id-6898 .events-filter-row > .events-filter-button,
body.page-id-6944 .events-filter-row > .events-filter-button {
    width: auto !important;
    max-width: none !important;
}
/* The two dropdowns are .ev-dd wrappers whose own rule sets the width, so they need naming
   directly; the generic child rule above does not reach them. The button inside takes the
   wrapper, so both the box and its label narrow together. */
/* S230 17/09/2026: same reason as the group rule above. Held at 601px and up so the two
   dropdowns keep Rob's desktop proportion, released below it so they match the search boxes
   and the label is not truncated. This query is closed by the brace that already sat below
   the rule, which was left over when the earlier dropdown-only wrap was removed. */
@media (min-width: 601px) {
body.page-id-6898 .events-filter-row > .ev-dd,

body.page-id-6944 .events-filter-row > .ev-dd,

body.page-id-6898 .events-filter-row > .ev-dd .ev-dd__btn,

body.page-id-6944 .events-filter-row > .ev-dd .ev-dd__btn {

    width: 65% !important;

    max-width: 65% !important;

    margin-left: auto !important;

    margin-right: auto !important;

}
}
body.page-id-6898 .events-filter-row > .ev-dd .ev-dd__btn,
body.page-id-6944 .events-filter-row > .ev-dd .ev-dd__btn {
    width: 100% !important;
    max-width: 100% !important;
}
/* end of 52.5a */
/* end of 52.5 */
/* end of 52.4 */
/* end of 52.3 */
/* end of 52.2 */
/* end of 52 */


/* ============================================================================
   53. THE MEMBERS DIRECTORY - ROB'S SIX, 14/09/2026
   His words are on each rule. Everything here is measured, not eyeballed; the
   numbers behind them are in Verification Suite/results/s220/.
   ========================================================================== */

/* 53.1 Rob: "This sentence is not centered." The hint under the search box was
   the only left-aligned line on the page. */
.members-search-note {
    /* S220, Rob: "This sentence is not centered." */
    text-align: center;
    /* S222 14/09/26, Rob: "Is the copy below the member search like a correct font for this site?
       It looks a bit thin." It was not the site's font: it computed Muli 400, the PARENT theme's
       face, because nothing here set a family. BRAND_GUIDE 4 makes body text Nunito Sans. */
    font-family: var(--font-body, 'Nunito Sans', sans-serif);
    font-weight: 500;
    /* S220, second pass, Rob: "I'm not sure that looks good though. The grays and the blues -
       Make it white panel gold border." So the hint sits on its own white panel. */
    background: var(--color-surface);
    border: 1.5px solid var(--color-gold);
    border-radius: var(--radius-md);
    padding: 14px 20px;
    max-width: 640px;
    margin: 14px auto 0;
}

/* 53.5 Rob: "that area at the bottom of the members page is very bland. Make it
   nicer. There's it it's all blue." The block had no surface of its own, so it
   sat as bare navy text on the page background. It is now a proper panel in the
   brand's own highlight cream with the gold border every other panel carries. */
.uks-guide-cta {
    /* S220, second pass, Rob: "Make the background white, make it a white panel.
       And leave the button slightly cream." */
    background: var(--color-surface);
    border: 1.5px solid var(--color-gold);
    border-radius: var(--radius-md);
    padding: 28px 32px;
    box-shadow: 0 2px 4px rgba(26, 26, 46, 0.04), 0 4px 12px rgba(26, 26, 46, 0.08);
}
/* The guide button is the only cream thing on the panel, so it is where the eye lands.
   !important because the canonical .btn-option block is armoured with it against the parent
   theme; per BRAND_GUIDE 9.7 the base rule is left alone and the selector is scoped instead. */
.uks-guide-cta .btn-option {
    background: #FFFBE6 !important;
}
.uks-guide-cta__title {
    font-family: var(--font-heading);
    font-weight: 700;
    color: var(--color-navy);
}
.uks-guide-cta__line {
    color: var(--color-text-secondary) !important;
    max-width: 46ch;
    margin-left: auto !important;
    margin-right: auto !important;
}
/* end of 53 */

/* ============================================================================
   54. THE CUSTOMISE WIDGET RAIL ICONS, S220 14/09/2026.
   Rob: "the widget icons seem to be left of center, and you can see the wish list one is the
   correct SVG... all the others are just bland. So change them just like you did with the side
   nav, make them all SVG versions and make sure they're dead center."
   They were WordPress's own dashicon FONT, and the class name is used in PHP data arrays and in
   the editor's JavaScript in the other lane's file, so swapping the markup would mean editing a
   dozen call sites in a file I do not hold. The glyph is replaced here instead: the font character
   is emptied and the brand mark is painted in its place as an SVG, centred by the background
   itself, which is what makes it dead centre rather than dependent on the font's own metrics.
   ========================================================================== */
#widget-sidebar .dashicons::before,
.widget-sidebar .dashicons::before {
    content: "" !important;
}
/* ITEM 82 (13/10/26, S246): this rule paints a 22px picture in a 24px box, but the PHP inline block
   #uks-rail-layout (mu-plugins/profile-system.php) sets `#widget-sidebar > .sidebar-icon .dashicons` to 18px
   !important, which out-ranks the plain `#widget-sidebar .dashicons` below, so About Me, Interests, Upcoming Events,
   Attendance and My Quote clipped 2px off every edge of the 22px picture. The doubled id raises this selector's
   specificity above the inline block's so the rule's own 24px box lands. The 24px value is this rule's own, the one
   the venue and organiser triggers already render at; the target is Rob's "cropped 2px" at zero. */
#widget-sidebar#widget-sidebar .dashicons,
.widget-sidebar .dashicons {
    background-repeat: no-repeat !important;
    background-position: center center !important;
    background-size: 22px 22px !important;
    width: 24px !important;
    height: 24px !important;
    display: block !important;
}
/* Interests */
#widget-sidebar .dashicons-star-filled,
.widget-sidebar .dashicons-star-filled {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M12 2.6l2.9 5.9 6.5.95-4.7 4.58 1.11 6.47L12 17.44l-5.81 3.06 1.11-6.47-4.7-4.58 6.5-.95z%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22 stroke-linejoin=%22round%22/%3E%3C/svg%3E") !important;
}
/* Add a Venue sigil */
#widget-sidebar .dashicons-store,
.widget-sidebar .dashicons-store {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M3.2 9.6h17.6v11.2H3.2z%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22 stroke-linejoin=%22round%22/%3E%3Cpath d=%22M2.2 5.2h19.6l-1.3 4.4H3.5z%22 fill=%22%23031B83%22/%3E%3Crect x=%229.6%22 y=%2213.4%22 width=%224.8%22 height=%227.4%22 fill=%22%23031B83%22/%3E%3C/svg%3E") !important;
}
/* Add an Organiser sigil */
#widget-sidebar .dashicons-megaphone,
.widget-sidebar .dashicons-megaphone {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M3.4 9.4h4.3l8.6-4.9v15l-8.6-4.9H3.4z%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22 stroke-linejoin=%22round%22/%3E%3Cpath d=%22M7.7 14.6v4.3a1.7 1.7 0 0 0 3.4 0v-2.4%22 fill=%22none%22 stroke=%22%23031B83%22 stroke-width=%221.6%22 stroke-linecap=%22round%22/%3E%3Cpath d=%22M19 8.6a5 5 0 0 1 0 6.8%22 fill=%22none%22 stroke=%22%23031B83%22 stroke-width=%221.6%22 stroke-linecap=%22round%22/%3E%3C/svg%3E") !important;
}
/* Political Party sigil */
#widget-sidebar .dashicons-awards,
.widget-sidebar .dashicons-awards {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M8.9 13.8l-2.6 7.6 3.9-1.6 2.2 2.9 2.2-2.9 3.9 1.6-2.6-7.6z%22 fill=%22%23031B83%22/%3E%3Ccircle cx=%2212%22 cy=%228.6%22 r=%226.1%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22/%3E%3Ccircle cx=%2212%22 cy=%228.6%22 r=%222.3%22 fill=%22%23031B83%22/%3E%3C/svg%3E") !important;
}
/* Add a social link */
#widget-sidebar .dashicons-share,
.widget-sidebar .dashicons-share {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M8.6 10.8l6.6-3.6M8.6 13.2l6.6 3.6%22 stroke=%22%23031B83%22 stroke-width=%221.7%22 stroke-linecap=%22round%22/%3E%3Ccircle cx=%2217.6%22 cy=%225.6%22 r=%223.1%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22/%3E%3Ccircle cx=%226.4%22 cy=%2212%22 r=%223.1%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22/%3E%3Ccircle cx=%2217.6%22 cy=%2218.4%22 r=%223.1%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22/%3E%3C/svg%3E") !important;
}
/* Add an interest pill - the SECOND star, told apart by the control it sits in */
#widget-sidebar [aria-label="Add an interest pill"] .dashicons,
.widget-sidebar [aria-label="Add an interest pill"] .dashicons {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M2.8 11.3l8.5-8.5h7.9v7.9l-8.5 8.5z%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22 stroke-linejoin=%22round%22/%3E%3Ccircle cx=%2216.1%22 cy=%227.9%22 r=%221.6%22 fill=%22%23031B83%22/%3E%3Cpath d=%22M6.9 17.6v4.6M4.6 19.9h4.6%22 stroke=%22%23031B83%22 stroke-width=%221.8%22 stroke-linecap=%22round%22/%3E%3C/svg%3E") !important;
}

/* ----------------------------------------------------------------------------
   54.1 THE FOUR STANDARD-TIER RAIL ICONS THAT PAINTED NOTHING
   (S227 15/09/2026, backlog row 3 = N1 + CUST-18 rail half + GLOB-13 rail half + B13)

   THE FAULT. Section 54 above blanks EVERY dashicon in the rail with
   `content: "" !important` and then paints a brand SVG over it as a
   background-image. Six controls have that SVG. Four never got one, so on the
   Standard tier `About Me`, `Upcoming Events`, `Attendance` and `My Quote`
   drew four EMPTY GOLD CIRCLES. MEASURED live as cold_std22 at 1280: of six
   rail controls, four computed `background-image: none` with their dashicon
   font glyph already suppressed. The Premium tier never showed it, because its
   own five controls are all in the replaced set: that is why it survived every
   check taken on a Premium fixture.

   THE ARTWORK, and what is Rob's own and what is new.
   - Attendance is Rob's OWN `uks_icon_attendance()` glyph, unchanged in shape
     and colour (white rounded square, gold edge, green tick), reframed from its
     30x30 box into this family's frame.
   - About Me is Rob's OWN `uks_icon_person()` silhouette, recoloured into the
     rail's gold-fill-navy-stroke family so it sits with its five siblings.
   - Upcoming Events and My Quote are the only two NEW drawings, built in the
     same language as the six already here (gold #CC9900 fill, navy #031B83
     stroke 1.5). They are on the review sheet at
     results/s227/lead/rail_icon_sheet.png for Rob to accept or reject, and
     either is one line to change.

   THE VIEWBOX IS DELIBERATELY WIDER THAN 0 0 24 24. Section 54 paints these at
   `background-size: 22px 22px` inside an 18px box, centred, so 2px is cropped
   off every edge. Rather than change that for the six signed-off icons, which
   nobody asked for, these four carry a viewBox widened by the same 22/18 ratio
   so their art survives the crop complete.

   PROVEN by injection on the live customise page as cold_std22 at 1280:
   four controls computing `background-image: none` before, ZERO after.
   ---------------------------------------------------------------------------- */

/* About Me */
#widget-sidebar .dashicons-id,
.widget-sidebar .dashicons-id {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%22-2.67 -2.67 29.33 29.33%22%3E%3Cpath d=%22M4.6 21.1c0-4.1 3.3-6.6 7.4-6.6s7.4 2.5 7.4 6.6z%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22 stroke-linejoin=%22round%22/%3E%3Ccircle cx=%2212%22 cy=%228.7%22 r=%223.7%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22/%3E%3C/svg%3E") !important;
}
/* Upcoming Events */
#widget-sidebar .dashicons-calendar-alt,
.widget-sidebar .dashicons-calendar-alt {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%22-2.67 -2.67 29.33 29.33%22%3E%3Crect x=%223%22 y=%225.6%22 width=%2218%22 height=%2215.4%22 rx=%222%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22/%3E%3Cpath d=%22M3.8 10.4h16.4%22 stroke=%22%23031B83%22 stroke-width=%221.8%22/%3E%3Cpath d=%22M8 3.2v4M16 3.2v4%22 stroke=%22%23031B83%22 stroke-width=%221.8%22 stroke-linecap=%22round%22/%3E%3Crect x=%226.6%22 y=%2213%22 width=%223.2%22 height=%223.2%22 rx=%220.6%22 fill=%22%23031B83%22/%3E%3Crect x=%2212.6%22 y=%2213%22 width=%223.2%22 height=%223.2%22 rx=%220.6%22 fill=%22%23031B83%22/%3E%3C/svg%3E") !important;
}
/* Attendance */
#widget-sidebar .dashicons-yes-alt,
.widget-sidebar .dashicons-yes-alt {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%22-2.67 -2.67 29.33 29.33%22%3E%3Crect x=%221.4%22 y=%221.4%22 width=%2221.2%22 height=%2221.2%22 rx=%224.8%22 fill=%22%23FFFFFF%22 stroke=%22%23CC9900%22 stroke-width=%221.6%22/%3E%3Cpath d=%22M6.1 12.3 L10.3 16.7 L18.1 7.9%22 fill=%22none%22 stroke=%22%2327A644%22 stroke-width=%222.9%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22/%3E%3C/svg%3E") !important;
}
/* My Quote */
#widget-sidebar .dashicons-format-quote,
.widget-sidebar .dashicons-format-quote {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%22-2.67 -2.67 29.33 29.33%22%3E%3Crect x=%222.6%22 y=%224.2%22 width=%2218.8%22 height=%2213.6%22 rx=%223%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22/%3E%3Cpath d=%22M9.2 15.6 L6.3 20.1 L6.3 15.6 Z%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22 stroke-linejoin=%22round%22/%3E%3Cpath d=%22M7.0 8.9h3.5v3.5h-1.9c0 1.05.55 1.7 1.55 2.0l-.65 1.45c-1.65-.5-2.5-1.75-2.5-3.45z%22 fill=%22%23031B83%22/%3E%3Cpath d=%22M13.0 8.9h3.5v3.5h-1.9c0 1.05.55 1.7 1.55 2.0l-.65 1.45c-1.65-.5-2.5-1.75-2.5-3.45z%22 fill=%22%23031B83%22/%3E%3C/svg%3E") !important;
}
/* end of 54.1 */

/* ----------------------------------------------------------------------------
   54.2 THE FIFTEEN VENUE AND ORGANISER RAIL ICONS THAT PAINTED NOTHING
   (S230 17/09/2026, on Rob asking again why there are empty spots on the rails.)

   SAME FAULT AS 54.1, THIRD OCCURRENCE. Section 54 blanks EVERY dashicon in the
   rail with an empty content string and then paints a brand SVG back as a
   background-image, but only for the classes it lists. 54.1 swept the four
   Standard-tier misses. The business tiers were never swept, so MEASURED live on
   17/09/2026: VENUE drew 10 empty gold circles of 22 controls, ORGANISER drew 5
   of 20. Standard, Premium and Dating measured zero blanks, which is why every
   check taken on a member fixture kept missing it.

   Event Statistics and Venue Stats share dashicons-chart-bar, so fourteen
   drawings cover the fifteen controls.

   THE ARTWORK. All fourteen are new, in the same language as the six in 54 and
   the four in 54.1: 24x24 frame, gold #CC9900 fill, navy #031B83 stroke 1.5,
   round joins, no third colour. Price and Dress Code is a tag pointing DOWN-LEFT
   so it cannot be confused with the interest pill tag, which points up-left.
   Events Calendar carries a grid of days so it reads apart from Upcoming Events,
   which is dashicons-calendar-alt.
   -------------------------------------------------------------------------- */
/* Contact and Hours (VENUE) */
#widget-sidebar .dashicons-clock,
.widget-sidebar .dashicons-clock {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Ccircle cx=%2212%22 cy=%2212%22 r=%229.2%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22/%3E%3Cpath d=%22M12 6.6V12l4 2.4%22 fill=%22none%22 stroke=%22%23031B83%22 stroke-width=%221.9%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22/%3E%3C/svg%3E") !important;
}
/* Location and Map (VENUE) */
#widget-sidebar .dashicons-location,
.widget-sidebar .dashicons-location {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M12 2.4c-3.8 0-6.9 3.1-6.9 6.9 0 5 6.9 12.3 6.9 12.3s6.9-7.3 6.9-12.3c0-3.8-3.1-6.9-6.9-6.9z%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22 stroke-linejoin=%22round%22/%3E%3Ccircle cx=%2212%22 cy=%229.2%22 r=%222.6%22 fill=%22%23031B83%22/%3E%3C/svg%3E") !important;
}
/* Price and Dress Code (VENUE) */
#widget-sidebar .dashicons-tag,
.widget-sidebar .dashicons-tag {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M21.1 12.4l-8.7 8.7H4.5v-7.9l8.7-8.7a1.5 1.5 0 0 1 2.1 0l5.8 5.8a1.5 1.5 0 0 1 0 2.1z%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22 stroke-linejoin=%22round%22/%3E%3Ccircle cx=%227.9%22 cy=%2216.1%22 r=%221.6%22 fill=%22%23031B83%22/%3E%3C/svg%3E") !important;
}
/* Capacity (VENUE) */
#widget-sidebar .dashicons-groups,
.widget-sidebar .dashicons-groups {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Ccircle cx=%228.4%22 cy=%228.6%22 r=%223.2%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22/%3E%3Ccircle cx=%2216.6%22 cy=%229.6%22 r=%222.5%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22/%3E%3Cpath d=%22M2.8 19.6c0-3.2 2.5-5.4 5.6-5.4s5.6 2.2 5.6 5.4z%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22 stroke-linejoin=%22round%22/%3E%3Cpath d=%22M15.2 14.4c3.1 0 6 1.7 6 5.2h-4.6%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22 stroke-linejoin=%22round%22/%3E%3C/svg%3E") !important;
}
/* Amenities and Features (VENUE) */
#widget-sidebar .dashicons-yes,
.widget-sidebar .dashicons-yes {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Ccircle cx=%2212%22 cy=%2212%22 r=%229.2%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22/%3E%3Cpath d=%22M7.4 12.4l3.2 3.2 6-6.6%22 fill=%22none%22 stroke=%22%23031B83%22 stroke-width=%222.1%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22/%3E%3C/svg%3E") !important;
}
/* Type and Style (VENUE) */
#widget-sidebar .dashicons-art,
.widget-sidebar .dashicons-art {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M12 2.8c-5.1 0-9.2 3.9-9.2 8.8 0 4.9 4.1 8.8 9.2 8.8 1.5 0 2.2-1 2.2-2 0-1.4-1.3-1.8-1.3-3 0-1.1.9-2 2-2h1.9c2.6 0 4.4-1.8 4.4-4.2 0-3.6-3.9-6.4-9.2-6.4z%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22 stroke-linejoin=%22round%22/%3E%3Ccircle cx=%227.6%22 cy=%2210.8%22 r=%221.45%22 fill=%22%23031B83%22/%3E%3Ccircle cx=%2211.7%22 cy=%227.4%22 r=%221.45%22 fill=%22%23031B83%22/%3E%3Ccircle cx=%2216.1%22 cy=%229.1%22 r=%221.45%22 fill=%22%23031B83%22/%3E%3C/svg%3E") !important;
}
/* Events Calendar (VENUE) */
#widget-sidebar .dashicons-calendar,
.widget-sidebar .dashicons-calendar {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Crect x=%223.2%22 y=%225%22 width=%2217.6%22 height=%2215.4%22 rx=%222.2%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22/%3E%3Cpath d=%22M3.2 9.7h17.6%22 stroke=%22%23031B83%22 stroke-width=%221.5%22/%3E%3Cpath d=%22M7.9 2.9v3.6M16.1 2.9v3.6%22 stroke=%22%23031B83%22 stroke-width=%221.9%22 stroke-linecap=%22round%22/%3E%3Ccircle cx=%228%22 cy=%2213.5%22 r=%221.1%22 fill=%22%23031B83%22/%3E%3Ccircle cx=%2212%22 cy=%2213.5%22 r=%221.1%22 fill=%22%23031B83%22/%3E%3Ccircle cx=%2216%22 cy=%2213.5%22 r=%221.1%22 fill=%22%23031B83%22/%3E%3Ccircle cx=%228%22 cy=%2217.1%22 r=%221.1%22 fill=%22%23031B83%22/%3E%3Ccircle cx=%2212%22 cy=%2217.1%22 r=%221.1%22 fill=%22%23031B83%22/%3E%3C/svg%3E") !important;
}
/* Venue Stats (VENUE) and Event Statistics (ORGANISER) */
#widget-sidebar .dashicons-chart-bar,
.widget-sidebar .dashicons-chart-bar {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Crect x=%223.4%22 y=%2212.6%22 width=%224.2%22 height=%227.8%22 rx=%221%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22/%3E%3Crect x=%229.9%22 y=%228.2%22 width=%224.2%22 height=%2212.2%22 rx=%221%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22/%3E%3Crect x=%2216.4%22 y=%224.2%22 width=%224.2%22 height=%2216.2%22 rx=%221%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22/%3E%3C/svg%3E") !important;
}
/* Venue Reviews (VENUE) */
#widget-sidebar .dashicons-star-half,
.widget-sidebar .dashicons-star-half {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M12 2.6l2.9 5.9 6.5.95-4.7 4.58 1.11 6.47L12 17.44l-5.81 3.06 1.11-6.47-4.7-4.58 6.5-.95z%22 fill=%22none%22 stroke=%22%23031B83%22 stroke-width=%221.5%22 stroke-linejoin=%22round%22/%3E%3Cpath d=%22M12 2.6l-2.9 5.9-6.5.95 4.7 4.58-1.11 6.47L12 17.44z%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22 stroke-linejoin=%22round%22/%3E%3C/svg%3E") !important;
}
/* Owner Contact (VENUE) */
#widget-sidebar .dashicons-businessman,
.widget-sidebar .dashicons-businessman {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Ccircle cx=%2212%22 cy=%228%22 r=%223.9%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22/%3E%3Cpath d=%22M4.4 21.1c0-4.3 3.4-6.9 7.6-6.9s7.6 2.6 7.6 6.9z%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22 stroke-linejoin=%22round%22/%3E%3Cpath d=%22M12 14.4l-1.6 3.1 1.6 3.3 1.6-3.3z%22 fill=%22%23031B83%22/%3E%3C/svg%3E") !important;
}
/* About (ORGANISER) */
#widget-sidebar .dashicons-info,
.widget-sidebar .dashicons-info {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Ccircle cx=%2212%22 cy=%2212%22 r=%229.2%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22/%3E%3Ccircle cx=%2212%22 cy=%227.6%22 r=%221.35%22 fill=%22%23031B83%22/%3E%3Cpath d=%22M12 10.9v6.1%22 stroke=%22%23031B83%22 stroke-width=%222.3%22 stroke-linecap=%22round%22/%3E%3C/svg%3E") !important;
}
/* Events Timeline (ORGANISER) */
#widget-sidebar .dashicons-list-view,
.widget-sidebar .dashicons-list-view {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Ccircle cx=%225.6%22 cy=%226.6%22 r=%222.1%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22/%3E%3Ccircle cx=%225.6%22 cy=%2212%22 r=%222.1%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22/%3E%3Ccircle cx=%225.6%22 cy=%2217.4%22 r=%222.1%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22/%3E%3Cpath d=%22M10.5 6.6h10M10.5 12h10M10.5 17.4h10%22 stroke=%22%23031B83%22 stroke-width=%221.9%22 stroke-linecap=%22round%22/%3E%3C/svg%3E") !important;
}
/* Event Types (ORGANISER) */
#widget-sidebar .dashicons-chart-pie,
.widget-sidebar .dashicons-chart-pie {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Ccircle cx=%2212%22 cy=%2212%22 r=%229.2%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22/%3E%3Cpath d=%22M12 12V2.8a9.2 9.2 0 0 1 9.2 9.2z%22 fill=%22%23031B83%22/%3E%3C/svg%3E") !important;
}
/* Accepts Payments (ORGANISER) */
#widget-sidebar .dashicons-money-alt,
.widget-sidebar .dashicons-money-alt {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Crect x=%222.6%22 y=%226%22 width=%2218.8%22 height=%2212%22 rx=%222.2%22 fill=%22%23CC9900%22 stroke=%22%23031B83%22 stroke-width=%221.5%22/%3E%3Ccircle cx=%2212%22 cy=%2212%22 r=%223%22 fill=%22none%22 stroke=%22%23031B83%22 stroke-width=%221.9%22/%3E%3Cpath d=%22M5.9 9.4v5.2M18.1 9.4v5.2%22 stroke=%22%23031B83%22 stroke-width=%221.7%22 stroke-linecap=%22round%22/%3E%3C/svg%3E") !important;
}
/* end of 54.2 */


/* end of 54 */

/* ============================================================================
   55. THE ORGANISER'S CANCEL PANEL, S220 14/09/2026.
   Rob: "the cancellation panel looks terrible give it a white background and the spacing, the gaps
   vertically between each row and each element is all off, it should be uniform and symmetrical
   above and below the button for example".
   The panel used to be styled by an inline <style> block inside event-system.php, where each child
   brought its own margin, which is how the gaps ended up uneven. That block is being deleted by the
   other lane so this file is the single owner. Same approach as the ticket card: the panel is a
   flex column and its GAP is the only thing that sets vertical space, so nothing can drift again.
   ========================================================================== */
.ev-row__cancelpanel { width: 100%; }
.event-cancel-controls {
    width: 100%;
    max-width: 520px;
    margin: 0 auto;
    padding: var(--sp-lg);
    box-sizing: border-box;
    text-align: center;
    background: var(--color-surface);
    border: 1.5px solid var(--color-gold);
    border-radius: var(--radius-md);
    /* ONE rhythm. Every child's own vertical margin is stood down below. */
    display: flex;
    flex-direction: column;
    gap: var(--sp-lg);
    align-items: center;
}
.event-cancel-controls > * {
    margin-top: 0;
    margin-bottom: 0;
    width: 100%;
}
.event-cancel-controls__label {
    font-size: 14px;
    line-height: 1.45;
    color: var(--color-navy);
}
.event-cancel-controls__message {
    box-sizing: border-box;
}
.event-cancel-controls__hint {
    font-size: 13px;
    line-height: 1.5;
    color: var(--color-text-secondary);
}
/* The button is the one thing that must not stretch, and the gap either side of it is the same
   16px as every other gap, which is the "symmetrical above and below the button" he asked for. */
.event-cancel-controls > .btn,
.event-cancel-controls > button,
.event-cancel-controls__actions {
    width: auto;
    align-self: center;
}
.event-cancel-controls__done {
    padding: 0;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.5;
    color: #C41C1C;
    text-align: center;
}
/* end of 55 */


/* ============================================================================
   56. THE PAGE CONTAINER FOLLOWS THIS SITE'S BREAKPOINTS, NOT BOOTSTRAP'S (D-513)
   S222 14/09/26, VC 08. Rob, by AskUserQuestion, on being shown a 1024 screen
   rendering every page in a 720px column with 304px of screen empty:
     "any particular screenwidth sticks to that layout until the next breakport.
      So 768 up to 1023 should be the same layout as 768, and then 1024 onwards
      has its own layout. So at 990, it should be displayed as if it's 768, and
      as 1150, it should be displayed as if it is 1024... Those should be the
      global rules on all the layouts across every page?"

   THE CAUSE. The parent theme (theme-static.min.css) steps .container at
   Bootstrap's widths, not ours: max-width 570 from 576, 720 from 768, 1100 from
   1150, 1390 from 1440. So everything from 1024 to 1149 inherits the 768 layout.
   Measured live: 720px of content in a 1024 screen, and 720 in a 1140 screen
   (420px empty). It is also why the /events/ featured strip drew ONE card per
   row there: the strip measured 607.50 at 1024 and two 310px cards plus their
   24px gap need 644.

   THE LADDER. 600 / 768 / 1024 / 1280, and nothing steps between them. 1024 to
   1279 is a FIXED 994px so that 1024, 1150 and 1279 render identically, which is
   what Rob asked for. Below 600 the container stays full width.

   THE TOP END IS DELIBERATELY UNTOUCHED (Rob, same exchange): "1440 was another
   breakport used early on but not with everything so I think it should stay...
   leave it as it is today 'cause the top end looks good." So 1280 to 1439 keeps
   the theme's 1100 and 1440 up keeps its 1390. Proper widescreen is post-launch.

   WHY !important. page-polish.css is enqueued BEFORE theme-static.min.css (sheet
   9 against sheet 16, read off document.styleSheets on the live page), so at
   equal specificity the parent theme wins. The same reason section 42.0.5 gives.

   PROVEN BY INJECTION BEFORE DEPLOYMENT on /events/, /venues/, /members/ and
   /blog/ at fourteen widths (360, 560, 600, 767, 768, 1023, 1024, 1150, 1279,
   1280, 1440, 1536, 1919, 1920): 1024/1150/1279 all 994 with two featured cards
   per row, every other band unchanged, zero horizontal overflow anywhere.
   ============================================================================ */

/* 56.1 600 to 767 - the 600 layout holds (the theme starts it at 576) */
@media (min-width: 576px) and (max-width: 599.98px) {
    .container,
    body .elementor-section.elementor-section-boxed > .elementor-container {
        max-width: 100% !important;
        padding-left: 30px !important;
        padding-right: 30px !important;
    }
}
@media (min-width: 600px) and (max-width: 767.98px) {
    .container,
    body .elementor-section.elementor-section-boxed > .elementor-container {
        max-width: 570px !important;
        padding-left: 35px !important;
        padding-right: 35px !important;
    }
}

/* 56.2 1024 to 1279 - its own layout, fixed so 1024, 1150 and 1279 are identical */
@media (min-width: 1024px) and (max-width: 1279.98px) {
    .container,
    body .elementor-section.elementor-section-boxed > .elementor-container {
        max-width: 994px !important;
        padding-left: 15px !important;
        padding-right: 15px !important;
    }
    body .uksp-section.uksp-section-boxed > .uksp-container {
        max-width: 994px !important;
    }
    .uksp-column-gap-default > .uksp-row > .uksp-column > .uksp-element-populated {
        padding-left: 15px !important;
        padding-right: 15px !important;
    }
    .uksp-section.uksp-section-boxed > .uksp-container .uksp-container {
        margin-left: -15px !important;
        margin-right: -15px !important;
    }
}

/* 56.3 1280 to 1439 - the theme's own 1100, restated so the 1150 step cannot
   split this band in two (the theme changes padding from 15 to 25 at 1150). */
@media (min-width: 1280px) and (max-width: 1439.98px) {
    .container,
    body .elementor-section.elementor-section-boxed > .elementor-container {
        max-width: 1100px !important;
        padding-left: 25px !important;
        padding-right: 25px !important;
    }
}
/* end of 56 */


/* ============================================================================
   57. THE CANCEL CONTROLS' LABEL SITS ON THE ICON'S CENTRE LINE (T-S220-007)
   S222 14/09/26, VC 08. Rob, on the My Events cancel control: the label "sits a
   tad high against its icon". MEASURED on the live button with the canvas metric
   method: the icon is dead centre of the button (0.000px) and the label's
   cap-height midpoint sat 0.500px ABOVE it, which is a whole device pixel at
   dpr 2. It could not be fixed while the label was a bare text node inside the
   flex button, so the other lane wrapped both labels in span.ev-row__cancel-label
   (event-system.php ~2384 and 6.9d.5); the span ships with no styling of its own.
   Half a pixel down puts the cap centre on the icon's centre line.
   ============================================================================ */

/* S224 15/09/26, item 212, REVERTED ON ROB'S OWN WORD: "I think it actually looked better when it
   was 0.5 pixel high, it just seems to have rendered slightly better? Revert it back to what it
   was before, even though that goes against everything I normally say because it should just be
   dead center." So the nudge is gone and the label reads half a pixel high again, as it did.
   HIS NOTE FOR LATER, recorded and NOT acted on: "technically, if you can't get it dead center,
   it's because the button itself is the wrong height. We've been through this with the icons on
   the side nav. Do not start changing button sizes now though, just make a note of it." The span
   itself stays: the other lane put it there and it is what any future fix would hang on. */
/* S246 13/10/26, item 69 (Rob's list of the 16th of September, item 16: "On My Events, the cancel panel's toggle label sits high
   against its icon."). Rob's S224 note stands: the button is NOT resized (34px, a 14px content box). The value comes from his
   own wording (the label centred on the icon) and from the ink measurement at dpr 8 on example_ben_hollis, 1280 and 360, eight
   sub-pixel page positions (results/s246/item69/PROOF.md): the icon is a 14px box, the label was a 13px line box, so flex centring
   put it 0.5px down and the capital read -0.75 against the icon's ink midline on two of the three toggles. The label now is a
   whole 14px box (13px line plus 1px top padding, offset 0 in the content box) and reads +0.25 at every position. The dormant
   position: relative / top: 0 of the reverted S224 nudge moved nothing and is replaced by this rule. Scoped to .ev-row__cancel
   because the same span is the whole label of the panel's own "Cancel this event" button and of the event page's cancel control,
   which have no icon and are not touched. */
.ev-row__cancel .ev-row__cancel-label {
    line-height: 13px;
    padding-top: 1px;
}
/* end of 57 */


/* ============================================================================
   58. NOTHING PAINTS A FOCUS RING FOR A MOUSE (D-514) - THE BACKSTOP
   S222 14/09/26, VC 08. Rob: "focuses should only be used if people start using
   tab to scroll. You should never see them any other time." Every focus ring
   this theme owns is now gated on html[data-nav="kbd"] at its own rule (section
   50's sitewide outline, section 48's, and every gold glow on an input), which
   the marker script sets on a real Tab press and clears on any pointer press.
   :focus-visible alone could not do it: Chrome matches :focus-visible on a TEXT
   FIELD for a plain mouse click, which is how the organiser cancel panel came to
   open showing a ring on its auto-focused reason box.

   This section is the backstop for rings this theme does NOT own: the parent
   theme, BuddyPress, PMPro, Elementor and the browser default. It fires only
   while the person is using a pointer, and it touches OUTLINE alone. box-shadow
   is deliberately left alone here: several controls carry a real design shadow
   at rest (the search inputs and filter buttons carry 0 2px 6px rgba(0,0,0,.12))
   and a blanket box-shadow:none would strip that shadow for as long as the
   control held focus.
   ============================================================================ */

html[data-nav="pointer"] a:focus,
html[data-nav="pointer"] button:focus,
html[data-nav="pointer"] input:focus,
html[data-nav="pointer"] select:focus,
html[data-nav="pointer"] textarea:focus,
html[data-nav="pointer"] summary:focus,
html[data-nav="pointer"] [tabindex]:focus,
html[data-nav="pointer"] .btn:focus {
    outline: none !important;
    outline-offset: 0 !important;
}

/* 58.1 THE LOGIN FORM, the one place a ring still came from a PLUGIN.
   S222 14/09/26. With our own rule gated, Paid Memberships Pro's own focus ring showed through on
   a mouse click: variation_1.css `.pmpro_section #loginform .input:focus` paints
   `rgba(0,123,255,.25) 0 0 0 3.6px`, a stock Bootstrap blue, measured live on /login/. It had been
   masked by the !important our rule used to carry. box-shadow:none is safe on these fields
   specifically: at rest they carry no shadow at all (measured).
   And the other half: the sitewide gold outline never reached these inputs, because the login
   block's own inline rule carries `outline: none !important` at the same specificity as ours and
   the inline block loads after this file. `body` in the selector settles it on merit. */
html[data-nav="pointer"] #loginform input:focus,
html[data-nav="pointer"] .login-form-wrapper input:focus,
html[data-nav="pointer"] .pmpro_section #loginform input:focus {
    box-shadow: none !important;
}
html[data-nav="kbd"] body #loginform input:focus,
html[data-nav="kbd"] body .login-form-wrapper input:focus {
    outline: 2px solid var(--color-gold, #CC9900) !important;
    outline-offset: 2px !important;
}
/* end of 58 */

/* ============================================================================
   66. THE CARD'S TWO BUTTONS STACK ON THE NARROWEST PHONES (S222, Rob 14/09/26)
   Rob, shown the member card at 360 side by side and stacked: "Stack them at
   360", and not on the wider phone band. A pair inside the 79px each gets at
   360 leaves the label 11.4px from each edge against his 15px rule (D-512), so
   below 600 the pair becomes a column and each button takes the card's width,
   which restores the 15px. Measured at 360: the card grows about 45px.
   One rule on the shared card, so it holds on events, venues, organisers and
   members alike (D-511, one card design for every listing).
   ============================================================================ */
/* S224 14/09/26, Rob refining item 225 after seeing it live: "only when they're side by side
   should the buttons be the same size, because then it looks even left to right. But when they're
   vertically stacked like that, it actually looks okay that the buttons are different sizes. So
   leave it when it's vertically stacked." So the equal-width grid track applies to the ROW only;
   stacked, justify-items: center lets each button shrink to its own label with its 15px. */
/* S245 item 74 (ROUND2_LIST entry 74, S9-21; Rob, the 16th of September 2026: "The members carousel on a
   phone has far more space below the card than above."). MEASURED live at 360, 375, 390, 414 and 430 as a
   member whose cards carry no Favourite control (example_ava_thornton): every slot of the members carousel is
   610.28px tall, because the carousel row stretches every slot to its tallest card, and the tallest card was
   the member's OWN one. Its two hidden stand-ins (event-system.php 18031 to 18034, D-597) were stacked by this
   rule into 90px, against the 40px of the lone Report button on every other card, so the other 22 cards
   (560.28px) stood in a 610.28px slot with 15px above them and 65px below. At 600px and above the stand-ins
   sit side by side as one 40px row and every card is 560.28px, the equal height D-597 asks for (Rob, the 17th of
   September 2026: "keep every card the same height with an empty row where the data is missing"). So the
   stand-in row now stacks only where the real row stacks: in a members list where no card carries a Favourite
   control (.member-fav-btn) there is no pair to match, and the stand-in row keeps the flow of the base rule at
   52.4 (grid-auto-flow: column, the 600px-and-above value). Every real row, every list that does carry a
   Favourite control, the pair Rob ruled to stack at 360 (the 14th of September 2026), and every width from
   600px up keep this rule exactly as it was. :where() keeps the specificity at (0,1,0). */
@media (max-width: 599.98px) {
    .uks-card__actions:not(:where(body.directory.members #buddypress #members-list:not(:has(.member-fav-btn)) .uks-card__actions:has(> .uks-card__btn--placeholder))) {
        grid-auto-flow: row;
        align-items: center;
        justify-items: center;
    }
    .uks-card__actions .uks-card__btn {
        width: auto;
    }
}
/* end of 66 */


/* ============================================================================
   67. THE GALLERY'S COUNTER BOXES (S222, Rob 14/09/26)
   Rob, with a picture of the two boxes: "those two boxes are just weird and
   wrong. There's already a little badge next to the photos label on the gallery
   that says how many photos there are, so you don't need that left-hand box",
   then: "Remove the left box, tidy the right box".

   MEASURED before: .gal-stats was still a three column grid of 150px tracks with
   only two cards in it, so the pair sat left of the title; the quota row had
   100px to fit "Photos" and "1 / Unlimited", which is why they crowded into each
   other; the bar's track was rgba(26,26,46,.08), a grey wash, and its fill
   #FFD700, neither of them brand colours; and a bar filling against "Unlimited"
   measures nothing, so it is not drawn on an uncapped tier.

   THE DELETION IS NOW DONE (D-243, delete never hide). The code lane deleted the
   left card's markup from profile-system.php on 15/09/2026 (S226, ps4), so the
   hide rule that used to sit here has been removed with it: with the markup gone
   and UKS_GALLERY_VIDEO_ENABLED false, the storage card Rob KEPT becomes the
   first child and that rule would have hidden it instead, leaving an empty band
   under My Gallery. Measured by ps4 on the live page with the deletion injected:
   .gal-stats went from two children to one, the survivor computed display:none
   and 0 x 0, and the wrapper's height went 63.19px to 0 at both 1280 and 360.
   SO THE TWO CHANGES ARE BOTH-OR-NEITHER, IN BOTH DIRECTIONS: their PHP without
   this file hides the card Rob kept; this file without their PHP brings back the
   card he asked to be removed. Pairing recorded in DEPLOY_IN_THE_MORNING.md.
   Numbered 67 because 59 to 65 are already taken elsewhere in this file (LB-382).
   ============================================================================ */

.gal-stats {
    grid-template-columns: 260px;
    justify-content: center;
}
.gal-stats > .gal-stat {
    padding: 14px 18px;
}
.gal-storage {
    width: 100%;
}
.gal-storage__row {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: 5px;
    white-space: nowrap;
}
.gal-storage__row > span:first-child {
    font-family: var(--font-heading, 'Montserrat', sans-serif);
    font-weight: 700;
    font-size: 11px;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--color-navy, #031B83);
}
.gal-storage__bar {
    background: var(--color-cream, #FFFBE6);
    border: 1px solid var(--color-gold, #CC9900);
}
.gal-storage__fill {
    background: var(--color-gold, #CC9900);
}
#gal-storage[data-limit="999"] .gal-storage__bar {
    display: none;
}
/* end of 67 */

/* ============================================================================
   68. THE OWNER'S PENDING PHOTO MARKER (S222, Rob 14/09/26)
   Rob, shown the gold pill lying across his own photos: "do a little circle on
   the top right corner, gold border, white background, red warning triangle
   with exclamation mark in the middle, and then on hover, it explains that only
   they can see the image at the moment, and once admin have verified it adheres
   to our TOS, it will be shown publicly."

   So the pill becomes a 26px badge in the corner and the wording moves into the
   hover. The badge is drawn, not written: the triangle is an inline SVG in the
   background, so no new artwork file is needed. The full wording remains the
   button's accessible text while CSS reduces its visible face to the warning mark.
   The card's dashed border goes back to the site's own solid gold: the dashed
   edge read as an error, and the badge now says what the state is.
   ============================================================================ */

.photo-card--pending {
    border-style: solid;
}
.photo-card__pending-pill {
    -webkit-appearance: none;
    appearance: none;
    display: block;
    margin: 0;
    box-sizing: border-box;
    position: absolute;
    top: 8px;
    right: 8px;
    left: auto;
    transform: none;
    z-index: 3;
    width: 26px;
    height: 26px;
    padding: 0;
    border-radius: 50%;
    border: 2px solid var(--color-gold, #CC9900);
    /* S227 item 228, Rob: the mark is "not dead centre of the new button". Measured from
       pixels at dpr 2, 3, 4 and 8 it sat exactly 0.500px RIGHT of the badge centre at every
       one of them. The badge is 26px with a 2px ring, so the positioning area is 22px and a
       15px glyph needs a 3.5px offset, which the renderer rounds to a whole pixel: it can
       never be centred. 16px needs 3px exactly and measures 0.000. The path also moves up
       0.3 viewBox units because the triangle ran 3.4 to 21.2 about a centre of 12. */
    background: #FFFFFF url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 3.1 22.3 20.9H1.7Z' fill='%23C41C1C'/%3E%3Crect x='11' y='8.9' width='2' height='6' rx='1' fill='%23FFFFFF'/%3E%3Ccircle cx='12' cy='17.7' r='1.15' fill='%23FFFFFF'/%3E%3C/svg%3E") no-repeat center / 16px 16px;
    /* D-651 (S235 FIXER-SHADOWS-3, 24/09/26): was a navy shadow (rgba(3,27,131,.18)) - the gold
       token, replaced at source, one rule, no stacking. */
    box-shadow: var(--shadow-gold-hover);
    font-size: 0;            /* the wording is kept in the markup for a screen reader */
    line-height: 0;
    color: transparent;
    overflow: visible;
    pointer-events: auto;
    cursor: help;
}
/* D-651: pressed = no shadow. Background is left untouched on purpose - it is not a flat colour,
   it is the badge's own warning-triangle SVG painted via this same `background` shorthand, and
   swapping it to flat cream-hover on press would hide that icon (Rule 13). */
.photo-card__pending-pill:active {
    box-shadow: none;
}
/* the explanation, on hover of the badge or anywhere on the photo */
.photo-card__pending-pill::after {
    /* S234 21/09/2026 (F-095): the explanation said the photo was private until an admin had
       checked it, which has not been true since S199 lifted the hold-before-use gate: a pending
       photo is live to everybody and only its owner sees this badge at all. */
    content: "Checked by admin shortly";
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    /* the card carries overflow:hidden, so the explanation has to live INSIDE it: measured, a photo
       card is 190px wide with the badge 9px in from each edge, so 168px sits within the card at
       every size it is drawn and nothing is clipped. */
    width: 168px;
    padding: 9px 11px;
    border-radius: 10px;
    border: 1.5px solid var(--color-gold, #CC9900);
    /* S227 item 228, Rob: "the text is not centered and the background should be white not
       cream. I don't know why you seem to have defaulted to making every panel background
       light cream. The majority of panels are actually white background I believe." */
    background: #FFFFFF;
    color: var(--color-navy, #031B83);
    font-family: var(--font-body, 'Nunito Sans', sans-serif);
    font-size: 11.5px;
    font-weight: 600;
    line-height: 1.45;
    letter-spacing: 0;
    text-transform: none;
    text-align: center;
    white-space: normal;
    box-shadow: 0 6px 16px rgba(3, 27, 131, .18);
    opacity: 0;
    visibility: hidden;
    transition: opacity .15s ease, visibility .15s ease;
    z-index: 6;
}
.photo-card__pending-pill:hover::after,
.photo-card--pending:hover .photo-card__pending-pill::after,
html[data-nav="kbd"] .photo-card__pending-pill:focus-visible::after,
.photo-card__pending-pill.is-open::after {
    opacity: 1;
    visibility: visible;
}
@media (max-width: 599.98px) {
    .photo-card__pending-pill::after {
        width: 150px;
        right: -9px;
    }
}
/* end of 68 */
/* 69 THE CHECKBOX STANDARD (S222 14/09/26, CHK1, Rob's items 32, 33 and 36).
   ROB (32): "there's a massive gap between the checkbox and the first letter. There shouldn't be
   a gap that big. You do that all the time with checkboxes." ROB (33): "it's not aligned
   correctly, it sits on the same level as the text, and it's really far away from the first
   letter. There should be a standard uniform distance between the checkbox and the first letter
   all across the platform." ROB (36): "The checkbox is in the wrong place. It's too low and
   it's too far from the first letter."

   WHAT IS ACTUALLY HAPPENING. The member never sees the real <input>: Seeko sets it to opacity 0,
   adds `form-check-wrapper label-checkbox` to the label and draws its own box on an injected
   <span class="check-icon">. The theme's own rules are
     .form-check-wrapper { display:block !important; padding-left:calc(20px + 0.5rem);
                           margin-right:2rem; }
     .form-check-wrapper > .check-icon:before { top:calc((1.6*1rem - 20px)/2); width:20px;
                                                height:20px; transform:scale(0.7); }
   so three separate faults land on every checkbox on the site:
   (a) the drawn box is scaled down to 14px but the label still reserves 28px, so 11px of dead
       space exists before the text box even starts;
   (b) the label inherits text-align:center from the card, so the first line is centred inside
       what is left and the gap then changes with the length of the words. Measured from the
       painted ink at deviceScaleFactor 8 at 360: "Not applicable to this event" 17.25px,
       "No limit on numbers" 32.375px, "Make this an exclusive event for Premium members" 41.0px.
       Three rows on one form, three different gaps;
   (c) `top` is calculated from 1.6*1rem (25.6px), which is only true when the label's own font is
       16px, so every 13px checkbox row has its box 3.688px BELOW the cap centre of its text
       (measured, 50% coverage edges, dpr 8). At 1920 the same rows measure 5.4px low.
   The box also grows from 14px to 20px on hover and when ticked, so the gap could never have been
   uniform whatever padding was used.

   THE STANDARD. 12px from the painted box to the text box, which is --sp-md, the value the
   platform's own answer rows (.pf-opt) and the registration consent row (.terms-card) already
   use, and the same 12px VC 08 set on the panic list. The box is 20px in every state, the size
   the registration consent box and the panic box already use and the closest match to the 22px
   answer ring. 20px box + 12px = the 32px padding-left below. Vertically the box's painted centre
   is put on the first line's cap centre, measured at 0.716em below the top of a 1.6 line box
   (Montserrat, from the ink at dpr 8); `top` is that minus half of the 20px box.
   @property is needed because the theme gives the tick pseudo its own font-size:20px, so a bare
   em in the tick's `top` would resolve against 20px and drop the tick out of the box. Registered
   as a <length> it resolves once on the label and both pseudos inherit the same px value.

   SCOPE. :has(> input[type="checkbox"]) keeps this off the radio rows, which the theme wraps in
   the same class but which page-polish has already restyled as .pf-opt rings (the report reasons
   and the panic reasons). The pseudo-element rules additionally require a checkbox sibling for
   the same reason. MEASURED on the live site as carrying the theme wrapper: the event creation
   form (9 rows, all measured), the report modal rows and the suggest-location style pills. NOT
   measured, and listed here only because the theme stamps the wrapper on any label holding a
   checkbox: the panic "talk to a person" row, the peer-review qualifiers, the family attestation
   row and the venue no-screens toggle. Those four need a live look after this deploys; three of
   them need fixtures this agent could not create and the panic shield only renders for an
   eligible member on their own dashboard. The registration consent row is NOT reached: its input
   is not inside a label so the theme never wraps it, and it keeps its native 20px box and 12px
   flex gap, which is where this standard came from. The suggest-location style pills ARE wrapped
   but hide the drawn box and carry their own padding !important, so only the margin would have
   moved them, which is why margin-right is set in 69.2 on the event form alone and not here.
   AFTER, measured the same way: the gap is 12.0px on all nine rows of the event form at 1920,
   1280, 1024, 768, 600 and 360, ticked or not, and the vertical error is within 0.7px. */
@property --uks-cbx-top {
    syntax: "<length>";
    inherits: true;
    initial-value: 0px;
}
.form-check-wrapper:has(> input[type="checkbox"]) {
    /* One optical pixel below the font metric centres the painted 20px box on the full text ink. */
    --uks-cbx-top: calc(0.716em - 9px);
    padding-left: 32px;
    text-align: left;
}
.form-check-wrapper > input[type="checkbox"] + .check-icon::before,
.form-check-wrapper > input[type="checkbox"] + .check-icon::after {
    top: var(--uks-cbx-top);
}
.form-check-wrapper > input[type="checkbox"] + .check-icon::before {
    transform: none;
    border-color: var(--color-gold, #CC9900);
}
/* 69.1 The one row on the event form whose label font does not match its own text: the label is
   the theme's 1rem Montserrat while the span inside it is inline-styled 14px Nunito Sans, so the
   label's line box is 25.6px and the text in it is 14px. Matching the label to the text it
   renders is what lets the shared rule above land the box on the cap centre. It does not change
   the rendered text: the span's own inline font-size still wins. The residual on this row is
   1.0px, because its text is Nunito Sans and the constant above is measured from Montserrat;
   removing the inline font-family from that span (event-system.php line 8886) would take it to
   zero, and that is a markup change for the other lane, not this one. */
/* TICK-1 (S238, the 29th of September 2026): the rule was written as .ev-check alone and LOST to the theme's own
   .form-check-wrapper { font-size: 1rem }, so the label stayed 18px (16px on a phone) round its 14px words and the box
   stood 1.0 to 1.1px above the capitals' centre (measured on live). Named through the label and both classes it now
   wins, and the box measures 0.0px from the capitals' centre at 1920 to 600 and 0.125px at 360. */
label.ev-check.form-check-wrapper {
    font-size: 14px;
}
/* 69.2 The theme also puts margin-right:2rem on every wrapped label. These three labels are
   shrink-to-fit flex items centred in their card, so 32px of phantom right margin sits the whole
   row 16px left of the card's centre line and wraps it a line early: at 360 "No limit on numbers"
   broke over two lines and sat left of centre. Zeroing it here rather than on the shared rule
   because on the suggest-location style pills, which are wrapped by the theme too, the same change
   measurably reflows the pill rows (Outdoor moved up onto the line above), and no item asked for
   that. */
.ev-na-toggle,
.ev-check,
.ev-cap-unlimited {
    margin-right: 0;
}
/* end of 69 */

/* ============================================================
   S227 item 232, the wrong-font sweep (VC cloud 01, 15/09/26)
   ============================================================
   ROB: "whatever that incorrect font was, you need to grep the rest of the visible user-facing
   platform and make sure it's not being used elsewhere. It's highly likely that it is."
   It is. Eighteen live pages were driven and every element that paints its own text was read
   for its resolved family. The parent theme's Muli is inherited by all of the selectors below,
   none of which declares a font at all, which is why the declaration is added HERE rather than
   as a counter-rule somewhere else. Counts at the time of the sweep: 148 on the members grid,
   60 in Messages, 12 on customise, 3 on account, 3 on attendance, 2 on the dashboard, and one
   each on preferences, venues, organisers, pricing and the 404.
   BRAND_GUIDE 3.1 decides which: Nunito Sans for flowing copy, Montserrat for controls,
   badges and titles.
   NOT INCLUDED: the home page's own body copy, which is Elementor and off limits under
   BRAND_GUIDE 20, and which is written up for Rob instead. */
.uks-card__meta,
.uks-card__meta .activity,
.thread__preview,
.workspace__subtitle,
.section__hint,
.att-privacy__note,
.att-empty-state__hint,
.uks-guide-cta__line,
.uks-404__copy {
    font-family: var(--font-body), 'Nunito Sans', sans-serif;
}
.cal__nav-btn,
.widget-minimize-btn,
.card-badge,
.uks-404__title {
    font-family: var(--font-heading), 'Montserrat', sans-serif;
}
/* end of S227 item 232, the wrong-font sweep */

/* ============================================================
   S227: HAND-OFFS FROM THE CODE LANE: H2 (gl2): the gallery Tag-members picker, Rob item 52
   Written by Loose ends cloud 01 (S226) in results/s226/HANDOFFS_FOR_VC.md and copied
   here verbatim by the visual lane, because only this lane opens this file.
   ============================================================ */
/* ── The gallery's Tag-members picker (S226 gl2, Rob's item 52) ───────────────
   The dropdown itself is the canonical component and needs nothing. These rules
   cover only the parts that have no canonical equivalent: the search box, the
   option row's layout, and the uniform gaps Rob asked for. */
.gal-modal .gal-tag-dd { margin: 16px 0 0; }

.gal-tag-dd__trigger { width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.gal-tag-dd__caret { flex: 0 0 auto; transition: transform .15s ease; }
.gal-tag-dd__trigger--open .gal-tag-dd__caret { transform: rotate(180deg); }

.gal-tag-dd__menu { padding: 10px; }

.gal-tag-dd__search {
  width: 100%;
  box-sizing: border-box;
  padding: 10px 14px;
  margin: 0 0 10px;
  border: 2px solid #CC9900;
  border-radius: 10px;
  background: #FFFFFF;
  color: #031B83;
  font-family: 'Nunito Sans', sans-serif;
  font-size: 14px;
}
.gal-tag-dd__search::placeholder { color: #031B83; opacity: .55; }
.gal-tag-dd__search:focus { outline: none; border-color: #031B83; }

.gal-tag-dd__list { list-style: none; margin: 0; padding: 0; max-height: 40vh; overflow-y: auto; }
.gal-tag-dd__list > li + li { margin-top: 10px; }

.gal-tag-dd__option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 14px;
  border-radius: 10px;
  cursor: pointer;
}
.gal-tag-dd__name  { font-family: Montserrat, sans-serif; font-weight: 700; font-size: 14px; color: #031B83; }
.gal-tag-dd__state { font-family: Montserrat, sans-serif; font-weight: 700; font-size: 12px; color: #CC9900; white-space: nowrap; }
.gal-tag-dd__option--selected .gal-tag-dd__state { color: #27A644; }
.gal-tag-dd__option:focus-visible { outline: 2px solid #031B83; outline-offset: 2px; }

.gal-tag-dd__none,
.gal-tag-dd__empty {
  margin: 0;
  padding: 10px 14px;
  font-family: 'Nunito Sans', sans-serif;
  font-size: 14px;
  line-height: 1.5;
  color: #031B83;
  text-align: center;
}

/* Rob, item 52: "the vertical gaps between the rows is not uniform. There's a
   massive gap between the text and the done button." One value for every gap in
   this modal, and the actions row takes the same one. */
.gal-modal .gal-modal__title + * { margin-top: 16px; }
.gal-modal .gal-tag-dd + .gal-modal__actions,
.gal-modal .gal-tag-dd__empty + .gal-modal__actions { margin-top: 16px; }

/* ============================================================
   S227: HAND-OFFS FROM THE CODE LANE: H5 (ps2): the All Members count chip withheld at 10,000
   Written by Loose ends cloud 01 (S226) in results/s226/HANDOFFS_FOR_VC.md and copied
   here verbatim by the visual lane, because only this lane opens this file.
   ============================================================ */
/* S226 ps2 (Loose ends cloud 01), 15/09/26, T-S223-004. profile-system.php section 15.5b-iv empties
   the member-count badge at 10,000 on Rob's instruction ("keep that number until it gets to maybe ten
   thousand or something and then we'll just get rid of it"). The number goes, but this span is a 22px
   square cream chip with a gold border, so an empty one still draws an empty ring. This removes the
   chip when, and only when, it is empty. Below 10,000 nothing changes: the span is never empty.
   Measured by injection on the live page as cold_std22: without this rule the emptied span is
   22.00 x 22.00; with it, 0.00 x 0.00, and the tab reads "All Members". */
body.directory.members #buddypress li#members-all > a > span:empty{display:none !important}

/* ============================================================
   S227: HAND-OFFS FROM THE CODE LANE: H8 (es9): Rob item 31, the blank box on the create form
   Written by Loose ends cloud 01 (S226) in results/s226/HANDOFFS_FOR_VC.md and copied
   here verbatim by the visual lane, because only this lane opens this file.
   ============================================================ */
/* Rob's item 31 (S226 es9, 15/09/2026): the blank box between the "Publish event" note and the
   footer. The form's own bottom padding and the note's bottom margin are the only part of it any
   lane of ours owns; the rest is the parent theme's page wrappers. Measured before: 185px at 1280,
   172px at 360. */
.ev-page { padding-bottom: 24px; }          /* was 64px */
.ev-submit__note { margin-bottom: 8px; }    /* was 27px at 1280, 24px at 360 */


/* ============================================================
   71. THE TWO STOCK PMPro TEMPLATE PAGES (S227 pm3, 15/09/2026)
   ROW 17 of the older backlog = GLOB-56 + DASH-61.

   /billing/ (page 38) and /cancel-membership/ (page 39) are the only two PMPro
   template pages left: Membership Account (37), Membership Orders (42), Your
   Profile (45) and the invoice page were trashed on Rob's own instruction in
   S157 (D-243), and /membership-checkout/ has its own child-theme template and
   is already branded under .uks-registration.

   These two have NO template override, so they render PMPro's stock markup
   against PMPro's own base.css. PMPro publishes its palette as custom
   properties, so redefining five of them on the body class fixes the card
   border, the divider, the table cell borders, the corner radius and the
   near-black text in one place, rather than stacking counter-rules on PMPro's
   own selectors. The font is separate because PMPro does not tokenise it.

   Measured before -> after, live, at 1280 and 390:
     .pmpro_card  border #e8e8e8 1px -> #cc9900 1px, radius 8px -> 16px
     .pmpro_card / .pmpro_section / .pmpro_card_content  #222222 -> #031b83
     .pmpro_divider background #e8e8e8 -> #cc9900
     .pmpro_table th/td border #e8e8e8 1px -> #cc9900 1px
     body copy font Muli -> Nunito Sans
   ============================================================ */
body.pmpro-billing,
body.pmpro-cancel {
    --pmpro--color--contrast: var(--color-navy);
    --pmpro--color--border: var(--color-gold);
    --pmpro--color--border--variation: var(--color-gold);
    --pmpro--color--base-2: var(--color-gold);
    --pmpro--base--border-radius: var(--radius-md);
}
body.pmpro-billing .pmpro,
body.pmpro-cancel .pmpro {
    font-family: var(--font-body);
}
/* end of 71 */

/* 71.1 (R3-09/10, 24/09/2026): the no-membership state on /billing/ - still PMPro's stock
   markup, no template override (see §71 above). Rob (items 9+10): "You do not have an
   active membership." centred; "Choose a membership level" and "View Your Membership
   Account" both standard D-640 buttons (cream/gold border/navy/gold shadow at rest),
   stacked one per row, centred, uniform gap. .pmpro becomes the flex column so every
   child centres the same way.
   No gap is set on the flex column itself: .pmpro_actions_nav (PMPro's own wrapper
   around the second link) already carries padding: 16px 0 !important from the login
   page's button block (globalsocials_brand_css(), functions.php, unscoped so it reaches
   every page using that class), so its own top padding already supplies 16px of visual
   gap above the second button - matched here with an equal 16px margin-top on the first
   button rather than fighting the !important padding with a second, competing rule
   (rule of one: design around the declaration that already wins, don't stack another on
   top of it). The second button's own colour/shadow/pressed treatment is already covered
   by that same .pmpro_actions_nav a rule - only its position changes here. */
body.pmpro-billing .pmpro {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}
body.pmpro-billing .pmpro > a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-top: 16px;
    /* S235 item 9 (Rob, 24/09/2026): no line-height was set here, so this link inherited
       the 1.6 body copy value (22.4px) instead of the D-640 buttons' own line-height: 1 -
       measured by ink at dpr 8, "Choose a membership level" sat 0.81px low against the
       gold ring's own painted midline regardless of that line-height (line-height only
       changes the box's total height, not the font's own ascent/descent split against its
       line box, so it is set here to match every other D-640 button, and the remaining
       offset is closed by padding below). */
    line-height: 1;
    /* GATE-RERUN 25/09/2026 (gate 12): the prior ad-hoc bracketing above this line (9.5/11.5,
       claimed 0.19px high) was never measured by comparison.js's own ink gate and read 1px
       high once it was. Reverted to symmetric padding (Rob's stated preference over sub-pixel
       asymmetric tricks that only hold at one density) - sum kept at 21px so the button's own
       height is unchanged. Verified by comparison.js current R3-09-choose: label midline within
       gate 12's 0.5px tolerance. */
    padding: 10.5px 24px 10.5px;
    border-radius: 10px;
    border: 2px solid var(--color-gold);
    background: var(--color-cream);
    color: var(--color-navy);
    box-shadow: var(--shadow-gold-hover);
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 14px;
    text-decoration: none;
    white-space: nowrap;
}
body.pmpro-billing .pmpro > a:hover {
    background: var(--color-cream-hover);
}
body.pmpro-billing .pmpro > a:active {
    background: var(--color-cream-hover);
    box-shadow: none;
}
/* S235 item 9 (Rob, 24/09/2026): "the arrow has still not be placed on the vertical centre
   line - again, not using overlays and measuring by ink." "View Your Membership Account -"
   is PMPro's own stock link text (no theme file emits it - grepped, not found), wrapped in
   PMPro's .pmpro_actions_nav; that wrapper's own <a> rule lives in functions.php
   globalsocials_brand_css() UNSCOPED, because the SAME rule also styles the login page's
   Join Now / Lost Password links. Scope-bumped here to body.pmpro-billing alone (Rule of
   one: the wrong padding was the mistake, not the base rule) so the billing-page fix below
   cannot reach those - measured, the login page's own links are already within 0.5px of
   centred and this exact padding push moved them 1.4px low.
   Measured by ink at dpr 8: the whole label group (text + arrow) sat 1.38px low against the
   gold ring. But measured against the TEXT's own x-height (the painted bounds of "our" in
   "Your", which has no ascender or descender), the text itself is only 0.06px off the ring's
   centre - it is specifically the arrow glyph that sits low, 1.44px below that x-height
   midline. line-height and padding shift the whole line as one baseline-anchored unit; they
   cannot move one character of a single text node relative to the rest of the same run, and
   the arrow is plain text here (confirmed: element.childNodes is one #text node, no span or
   svg), not something this rule can reach. The fix below closes the group's offset against
   the button (1.38px low -> bracketed the same way as the choose button, first quantised
   step past centre) so the label as a whole reads centred; the arrow's own 1.44px lean below
   the text is a font-metric property of this glyph in Montserrat Bold, not a padding/
   line-height fault, and is reported to the coordinator rather than papered over with
   generated content standing in for PMPro's real link text. */
body.pmpro-billing .pmpro_actions_nav a {
    line-height: 1 !important;
    /* GATE-RERUN 25/09/2026 (gate 12): the prior 9.25/11.75 split (claimed near-centred by an
       ad-hoc script) measured 1.25px high through comparison.js's own ink gate. Reverted to
       symmetric padding, same 21px sum, matching the sibling "Choose a membership level"
       button. Verified by comparison.js current R3-09-view: within gate 12's 0.5px tolerance. */
    padding-top: 10.5px !important;
    padding-bottom: 10.5px !important;
}
/* end of 71.1 */

/* 71.2 (R3-09b/R3-09c, 25/09/2026): Rob, looking at /billing/ on desktop logged in with no active
   membership: "you need to add more to the page here, like it's really really short. The footer
   is halfway up the screen, it's just ridiculous. Make it a normal size screen and put everything
   on a white panel with a gold border, make all the vertical gaps neater and more uniform etc."

   TWO separate faults, two separate fixes.

   FAULT A - the footer rides up. Measured live before this rule: at 1920x1080 the whole content
   area (header + this page's few lines) was only 519.95px tall, so the footer sat at y=569.95 -
   nowhere near the bottom of a 1080px viewport. #page-wrapper is the parent theme's own wrapper
   around [header + main content] - everything ABOVE the footer, which is a sibling of
   #page-wrapper, not inside it. #page-wrapper has no min-height of its own; it simply shrinks to
   whatever the page's content needs, which is why a short PMPro stock page leaves the footer
   floating mid-screen instead of at the bottom. Scoped min-height: 100vh (not a fixed px calc, so
   it needs no header-height constant and holds at every width with no @media) forces
   [header + content] to be at least one full viewport tall, so the footer's top is always >=
   window.innerHeight. Measured after, live, at 1920/1280/360 (Claude, no membership): footer top
   1130 against innerHeight 1080 at all three - the 50px gap above the footer is D-650's own
   dashboard-to-footer constant, untouched.

   FAULT B - no panel, uneven gaps. The title ("Membership Billing") lives in .svq-page-header;
   the sentence and both D-640 buttons live in .pmpro, inside .entry-content - two SEPARATE
   sibling wrappers, both children of the WP post wrapper (post_class() emits "post-38 page
   type-page status-publish hentry" on it; .type-page.hentry, scoped to the body class, reaches it
   without a hardcoded numeric post id, so this survives either stock page keeping its own id).
   Made into the platform's one standard content-card panel (white, 1.5px gold border, 16px
   corners, soft shadow - verbatim from .uks-page-shell .card in this same file and the /contact/
   panel at body.page-id-3727 .uksp.uksp-3727 - see section 11.7 above): max-width 760px like
   .workspace (the platform's narrow dashboard-column width), centred, margin-top var(--sp-2xl)
   below the header exactly as the contact panel sits below ITS header.

   Uniform gap: made .type-page.hentry a flex column with gap: var(--sp-xl) (24px, the platform's
   card gap token) so title-block-to-content-block is 24px with no margin to fight. Both children's
   OWN inherited spacing was fighting this and had to be zeroed at the source: .svq-page-header
   carried 54px of its own top padding (site-wide rule, harmless to remove here since it only ever
   wrapped a title that is now inside this panel); .entry-content carries `padding: 1rem 1.25rem
   !important` from style.css (unscoped, used by ordinary post content everywhere else - left
   untouched there, beaten here only, at this specificity, with !important, because it is itself
   !important - a same-property scope-bump per CLAUDE.md Rule 4, not a stacked extra rule); the
   theme's own h1/.h2 rule gives every heading a 2rem / 1.5rem margin-bottom, zeroed here the same
   way. Below that, D-640's own two button rules are UNCHANGED per Rob's instruction to keep them
   (body.pmpro-billing .pmpro > a and .pmpro_actions_nav a, both above) except for the ONE spacing
   property each was carrying: .pmpro > a's margin-top and .pmpro_actions_nav's padding-top both
   move from the old ad-hoc 16px (chosen by the previous fixer only to dodge an !important, per
   that block's own comment, never as a designed gap value) to the same var(--sp-xl) token, so
   title, sentence, button 1 and button 2 all sit exactly one 24px gap apart, verbatim through the
   panel's own top/bottom padding too. Measured live after (Claude, no membership, 1920/1280/360),
   identically at all three widths with no @media anywhere in this block: the one
   real-element-to-real-element gap that does not cross a bare text node (button 1's own bottom
   edge to button 2's own top edge) reads exactly 24px; the panel's edges read the same 24px plus
   its own 1.5px border (25px from the panel's outer edge down to the title, 41px from button 2
   down through the kept .pmpro_actions_nav bottom padding to the panel's outer edge) - both
   fully accounted for and not a second, different gap value.

   Kept exactly as designed, untouched by this rule: the D-640 colour/shape/shadow/pressed
   properties on both buttons, .svq-breadcrumb, and every .pmpro_card / My Memberships /
   cancel-confirmation state PMPro renders for an account with an actual level - this panel and
   shell wrap whatever content PMPro puts inside .type-page.hentry, not one hardcoded message, so
   the same two rules cover every state (verified live: the no-membership message, the Free-tier
   "My Memberships" card, and the /cancel-membership/ "are you sure" card all sit correctly on the
   same panel with the footer below the fold).

   /cancel-membership/ (page 39, body.pmpro-cancel) is the other live stock PMPro template page -
   see the heading of section 71 above - and measured live with the same short/unpanelled fault
   (footer at y=769.75 of a 1080px viewport before this rule), so it gets the identical fix,
   scoped by its own body class throughout. The other three PMPro stock URLs named in the brief
   (/membership-account/, /membership-confirmation/, /membership-invoice/) were checked live and
   all three 404 - trashed already, D-243, S157 - nothing to fix, nothing rendered to flag. */
body.pmpro-billing #page-wrapper,
body.pmpro-cancel #page-wrapper {
    min-height: 100vh;
}
/* BILL-3 (Rob, 25/09/2026, second attempt): "the billing page panel looks very tight, looks a bit
   small ... use the rest of the panels on the dashboard pages as reference. Everything's supposed
   to be uniform and relative, don't just randomly make things up." BILL-2 measured this panel's
   width against ONE small .card inside the Account tab's Invoices section and found it already
   matched (760px) - left width untouched, fixed only the title's font-size - but that left the
   panel looking the same narrow box Rob was pointing at (results/s235/bill-2/summary.json,
   results/comparisons/BILL-2-1280.png).

   Re-measured live (results/s235/bill-3/reference-measurements.json): .workspace, the shared
   width envelope every dashboard tab's content sits inside, is the ONLY number that is identical
   across all three tabs the brief names (Account, Preferences, Messages) - 796px at 1280, 992px at
   1920, on all three. No single bordered element wraps 100% of any one tab's content (Account
   splits into 1-6 separate .card boxes per section; Preferences into .pf-hero/.pf-card/.pf-host;
   Messages into a thread-list box and a conversation box side by side), so .workspace itself, not
   any one card, is the only measured value that is genuinely common to "the dashboard pages" the
   brief points at. Two same-named .workspace rules exist in this file: 42.1 (line ~10068, the
   dashboard's own authored 760px) loses the cascade to a later, unrelated, unscoped Wish List rule
   (line ~17638, max-width:992px) - BILL-2 already flagged that collision as a pre-existing,
   out-of-scope bug and did not touch .workspace; this item does not touch it either. 992px is
   simply .workspace's own live, member-visible number, copied verbatim onto this panel's own
   max-width - the platform's dashboard-column width as it actually renders today, not the value
   that loses the cascade.

   Fits without overflow at both widths this changes (billing's own page container, the Seeko theme
   ".content-wrapper.container", measures 1100px at 1280 and 1390px at 1920 live - see the same
   evidence file). Padding (24px/var(--sp-xl)), border (1.5px gold), radius (var(--radius-md)),
   the title's 24px size and the D-650 50px footer gap were already measured matching in BILL-2 and
   are untouched here - width was the one value still open. Rule of one: only max-width changes,
   same property, same selector, no @media. */
body.pmpro-billing .type-page.hentry,
body.pmpro-cancel .type-page.hentry {
    display: flex;
    flex-direction: column;
    gap: var(--sp-xl);
    text-align: center;
    box-sizing: border-box;
    max-width: 992px;
    margin: var(--sp-2xl) auto 0;
    background: var(--color-surface);
    border: 1.5px solid var(--color-gold);
    border-radius: var(--radius-md);
    padding: var(--sp-xl);
    box-shadow: var(--shadow-sm);
}
body.pmpro-billing .type-page.hentry .svq-page-header,
body.pmpro-cancel .type-page.hentry .svq-page-header {
    margin: 0;
    padding: 0;
}
body.pmpro-billing .type-page.hentry h1.entry-title,
body.pmpro-cancel .type-page.hentry h1.entry-title {
    margin-bottom: 0;
}
body.pmpro-billing .type-page.hentry .entry-content,
body.pmpro-cancel .type-page.hentry .entry-content {
    margin: 0;
    padding: 0 !important;
}
body.pmpro-billing .pmpro > a,
body.pmpro-cancel .pmpro > a {
    margin-top: var(--sp-xl) !important;
}
body.pmpro-billing .pmpro_actions_nav,
body.pmpro-cancel .pmpro_actions_nav {
    padding: 0 !important;   /* 71.3 (26/09): the panel's own 32px flex gap is the only space above the account button now */
    justify-content: center;
}
/* 71.2 addendum (R3-09c, 25/09/2026): found while proving R3-09c at 360 wide - the panel above
   made an EXISTING bug visible rather than causing one. .entry-title/.page-title carries
   font-size: 56.8px !important and body.page .entry-title.page-title carries
   display: table !important (both unscoped, both elsewhere in this file / functions.php,
   neither touched here) so the title never wrapped to the viewport before; at 300px of content
   width inside this panel "Membership" alone does not fit at 56.8px and the table-display box
   overflowed the panel's right edge (confirmed 334.56px of title against 252px of available
   space). display:table is kept exactly as is - it is what shrink-wraps the gold underline to
   the text, elsewhere on the platform too, and is not this rule's to change. Only font-size is
   scoped here, with clamp() rather than a fixed breakpoint so it is not another @media step:
   56.8px is unchanged (the clamp's ceiling) from 1150px wide all the way up, matching the
   existing look exactly at 1920/1280; below that it eases down, reaching 32.4px at 360 and
   28.8px at 320 - measured live after, zero overflow either edge at 1920/1280/360/320. */
/* BILL-2 (Rob, 25/09/2026): "the billing page panel looks very tight, looks a bit small ...
   use the rest of the panels on the dashboard pages as reference. Everything's supposed to be
   uniform and relative, don't just randomly make things up." Measured live at 412 and 1280
   against the account dashboard (/members/me59f5d8e2bf62df4/account/, example_jack_penrose,
   #invoices .card and .workspace .card generally): this panel's own max-width (760px), padding
   (24px every side, var(--sp-xl)) and title-to-panel-top spacing (flush with that same 24px
   padding, no extra margin, same as .card__title) already matched the dashboard card system
   verbatim - see the measurements in Verification Suite/results/s235/bill-2/. The one value
   that did not was the title's own font-size: every dashboard title is ONE fixed size at every
   width (.section__title, the heading over the #invoices example the brief names, is 24px from
   360 to 1920, no clamp, no vw, no @media), while this rule used a clamp() the previous fixer
   had already marked a stopgap for an overflow bug, not a considered size. Measured live: at
   412 wide it computed to 37.08px and wrapped "Membership Billing" onto two lines. Replaced
   with the platform's own 24px, fixed at every width (the reference does not change by width
   either, so no @media here). Canvas text-metrics on the live font (Montserrat 600) put
   "Membership Billing" at 221px, comfortably inside the 304px/712px available at 412/1280 - one
   line, no wrap. Width, padding and the D-650 50px footer gap were already correct and stay
   untouched. */
body.pmpro-billing .type-page.hentry h1.entry-title,
body.pmpro-cancel .type-page.hentry h1.entry-title {
    font-size: 24px !important;
}
/* end of 71.2 */

/* ==========================================================================
   71.3 (T-S235-009, 26/09/2026): the billing panel's CONTENT laid out like the account tab's Membership
   section. Rob on BILL-3: "looks terrible. Why the massive blank spaces? Why is the top section so cramped?
   ... use the rest of the panels on the dashboard pages as reference. Everything's supposed to be uniform
   and relative." The blank spaces were PMPro's own layout inside the panel: a 245px-wide section with a
   72px bottom margin, an empty card body padded 12px/36px, a 36px title pad and a nav padded 24px/16px.
   Every value below is copied from the account tab (measured 26/09, results/s235/bill-4/): .section__title
   and .section__heading for the "My Memberships" heading, .tier-hero for the membership card (its 80 percent
   width at 1024 and up mirrors the tab's own container rule), .tier-hero__name for the level name,
   .tier-hero__actions for the card's actions. Nothing is invented and nothing is deleted (Rule 13).
   ========================================================================== */
body.pmpro-billing .pmpro,
body.pmpro-cancel .pmpro {
    display: block;
}
body.pmpro-billing .pmpro_section,
body.pmpro-cancel .pmpro_section {
    width: 100%;
    margin: 0 auto var(--sp-xl);   /* the panel's 32px rhythm between the card and the account button */
}
@media (min-width: 1024px) {
    body.pmpro-billing .pmpro_section,
    body.pmpro-cancel .pmpro_section { max-width: 80%; }   /* = .section .tier-hero at the dashboard's 1024 container width */
}
body.pmpro-billing .pmpro_section_title,
body.pmpro-cancel .pmpro_section_title {
    font-family: var(--font-heading);
    font-size: 24px !important;
    font-weight: 700;
    color: var(--color-navy);
    line-height: 1.2;
    margin: 0 0 var(--sp-xl);   /* .section__title + the .section__heading gap below it */
}
/* S238 PAY-1b: not on a card inside a card. PMPro nests a .pmpro_card inside its payment fieldset, which sits inside
   the card-change form (itself a .pmpro_card) on /billing/; this rule gave that inner card a second 32px frame
   (measured: about 100px of empty space above "Payment Information"). PMPro flattens nested cards itself
   (.pmpro_card .pmpro_card), so the nested one is left to PMPro. :where() keeps this rule's weight exactly. */
body.pmpro-billing .pmpro_card:not(:where(.pmpro_card .pmpro_card)),
body.pmpro-cancel .pmpro_card:not(:where(.pmpro_card .pmpro_card)) {
    background: var(--color-surface);
    border: 1.5px solid var(--color-gold);
    border-radius: var(--radius-md);
    padding: var(--sp-2xl);
    box-shadow: var(--shadow-sm);
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 0;   /* the tier hero's 24px rhythm is carried by margins below, so PMPro's empty card body adds no gap of its own */
    margin: 0;
}
body.pmpro-billing .pmpro_card_title,
body.pmpro-cancel .pmpro_card_title {
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 32px;
    line-height: 1.2;
    color: var(--color-navy);
    letter-spacing: -0.01em;
    padding: 0;
    margin: 0 0 var(--sp-lg);
}
body.pmpro-billing .pmpro_card_content,
body.pmpro-cancel .pmpro_card_content {
    padding: 0;
    margin: 0;
}
body.pmpro-billing .pmpro .pmpro_card .pmpro_card_actions,
body.pmpro-cancel .pmpro .pmpro_card .pmpro_card_actions {
    padding: 0 !important;   /* beats the login page's Join Now / Lost Password block in functions.php (10.2), which pads every
                                .pmpro_card_actions 16px 0 with !important; that block is not widened here because the checkout
                                page's discount control sits in the same class and depends on it */
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: var(--sp-sm);
}
/* end of 71.3 */

/* ==========================================================================
   71.4 (S238 PAY-1b, Rob, the 27th of September 2026: every new or changed text centred, every standard brand style
   kept). Since PAY-1, Manage subscription opens PMPro's own card form on /billing/ (form#pmpro_form.pmpro_card, PMPro's
   payment fieldset with its nested card, Update and Cancel). Measured before at 1280, 768 and 360 against the Account
   Information card above it: the form was 560px wide against 754 at 1280 (functions.php's checkout centring rule, now
   kept off this page there), its content sat hard on its gold edge (70.8, now kept off this page), about 100px of empty
   space stood above "Payment Information" (71.3 on PMPro's nested card, and PMPro's own 36px padding-top), the labels
   were left-aligned in the body face, the refusal notice was left-aligned, and Update and Cancel sat against the left
   edge as uppercase pills, with "View Your Membership Account" touching the card's bottom edge. Laid out here as the same card as Account Information (71.3's own values), with:
   - the labels in the Registration card box's label face, centred, as its "Card Number" is;
   - the boxes as the page's own fields (70.8a);
   - Update and Cancel as the D-640 standard button of 71.1 (2px gold, 10px radius, cream, navy, gold shadow at rest,
     darker cream and no shadow when pressed), centred side by side, wrapping centred on a narrow screen;
   - the notice as the checkout's own notice: the values of functions.php's "PMPro error/info messages" rules (2px,
     12px radius, 12px 16px, body face 600, the brand red for a refusal, white and navy on gold for PMPro's "updated"
     line) and the checkout's centring (S182 above). Those rules print on the checkout only (uksocials_pmpro_checkout_css
     returns early everywhere else), so this page names the same values itself.
   PMPro's own layout rules for this form are nested three and four classes deep, so the form is addressed by its id
   here (#pmpro_form), which outweighs them without !important. Only the button rule needs !important: it replaces
   functions.php's unscoped "PMPro submit button" rule on this page, and that rule is itself !important.
   ========================================================================== */
body.pmpro-billing #pmpro_form {
    margin: var(--sp-xl) 0;   /* 24px under Account Information and 24px above "View Your Membership Account" (was 0: the button sat on the card's edge) */
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
}
body.pmpro-billing #pmpro_form .pmpro_card_content {
    padding: 0;
    align-self: stretch;
    width: 100%;
}
body.pmpro-billing #pmpro_form #pmpro_payment_information_fields {
    margin: 0;
    padding: 0;
    border: 0;
    width: 100%;
}
body.pmpro-billing #pmpro_form #pmpro_payment_information_fields .pmpro_card {
    margin: 0;
    padding: 0;
    width: 100%;
}
body.pmpro-billing #pmpro_form #pmpro_payment_information_fields .pmpro_form_label {
    display: block;
    text-align: center;
    font-family: var(--font-heading);
    font-weight: 400;
    font-size: .8rem;
    color: var(--color-navy);
    margin: 0 0 6px;
}
body.pmpro-billing #pmpro_form #pmpro_message {
    box-sizing: border-box;
    width: 100%;
    margin: 0 0 var(--sp-xl);
    padding: 12px 16px;
    border: 2px solid var(--color-gold);
    border-radius: 12px;
    background: var(--color-surface);
    color: var(--color-navy);
    font-family: var(--font-body);
    font-weight: 600;
    text-align: center;
}
body.pmpro-billing #pmpro_form #pmpro_message.pmpro_error {
    background: var(--color-error-bg);
    border-color: var(--color-error);
    color: var(--color-error);
}
/* S238 STYLE (Rob, the 28th of September 2026: the waiting state wears the site's own waiting look, nothing new): PAY-3's
   asked and still waiting sentences for a card change are a wait, not a refusal. Marked by
   uksocials-shared-bank-authorisation.php 11A.6b.3, the box takes the pending values already in use (29.4.7
   .my-events-status.status-pending) on the 2px border above, now gold as the hold notice's; the limit stays red.
   WAIT-2 (Rob, the 28th of September 2026: he chose white with the gold border and navy text): the wash and the gold text are
   replaced by white and navy; the gold border stays. */
body.pmpro-billing #pmpro_form #pmpro_message.pmpro_error:has(> .uks-sba-pr-waiting) {
    background: #fff;
    border-color: #CC9900;
    color: #031B83;
}
body.pmpro-billing #pmpro_form .pmpro_form_submit {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: var(--sp-sm);
    margin: var(--sp-xl) 0 0;
}
body.pmpro-billing #pmpro_form .pmpro_form_submit .pmpro_btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin: 0 !important;
    padding: 10.5px 24px !important;
    border: 2px solid var(--color-gold) !important;
    border-radius: 10px !important;
    background: var(--color-cream) !important;
    color: var(--color-navy) !important;
    box-shadow: var(--shadow-gold-hover) !important;
    font-family: var(--font-heading) !important;
    font-weight: 700 !important;
    font-size: 14px !important;
    line-height: 1 !important;
    letter-spacing: normal !important;
    text-transform: none !important;
    white-space: nowrap;
    width: auto;
    height: auto;
}
body.pmpro-billing #pmpro_form .pmpro_form_submit .pmpro_btn:hover,
body.pmpro-billing #pmpro_form .pmpro_form_submit .pmpro_btn:focus {
    background: var(--color-cream-hover) !important;
    color: var(--color-navy) !important;
}
body.pmpro-billing #pmpro_form .pmpro_form_submit .pmpro_btn:active,
body.pmpro-billing #pmpro_form .pmpro_form_submit .pmpro_btn:disabled {
    background: var(--color-cream-hover) !important;
    box-shadow: none !important;
}
/* S238 STYLE (Rob, the 27th of September 2026: every standard style kept): ADDR's Billing Address card (functions.php
   7.3.5.3d) sits under the card fields inside this form, and it sat hard on them, its title 0px under the Expiration
   Date and CVC boxes at every width. It takes the page's 24px rhythm, the same space as above Update and Cancel. */
body.pmpro-billing #pmpro_form #uks-billing-address {
    margin-top: var(--sp-xl);
}
/* end of 71.4 */

/* ==========================================================================
   71.5 (S238 ADDR-c, Rob, the 28th of September 2026, on /billing/: "The billing address fields don't need to be so
   wide"; asked how wide: "take inspiration from other places on the dashboard pages"). Stripe's billing address field
   (functions.php 7.3.5.3d) on the Registration card box and on /billing/ ran the card's whole content width. It now takes
   the dashboard forms' own field width, copied from the Account page's Details form (42.15: .form-input max-width 80%,
   margin-inline auto, from a 600px #item-body up, nothing below; #item-body measured 15px narrower than the screen below
   1024, so the dashboard's fields turn full width under a 615px screen): 80% of the card's content, centred, and the
   full content width under 615px. Stripe draws its fields to the width of this mount point, so the width is set here
   and nowhere inside Stripe's frame (its appearance settings take no width). This replaces the inline full width
   (align-self: stretch; width: 100%) the mount point carried; it still needs a width of its own, because the
   Registration row (.uks-page-shell .form-row) centres its children and would shrink Stripe's frame to 300px.
   ========================================================================== */
#uks-billing-address #uks-address-element {
    box-sizing: border-box;
    align-self: center;
    width: 80%;
    max-width: 100%;
    margin-left: auto;
    margin-right: auto;
    /* ADDR-g (S238, Rob, the 28th of September 2026: "add a bit of margin above the top address field - the text above is
       way too close. All gaps are supposed to be uniform where possible."). MEASURED on live, inside Stripe's frame: the
       fields stand 16px apart (16.5px from painted border to painted border), and the note stood 6px over the first one
       (the 6px gap of its row on the checkout and of 71.6 on /billing/). The gap is set by what is PAINTED: the note's
       line box ends 3.25px under its lowest ink, so 7px here puts the lowest ink of the note 16.75px over the first
       field's border, a quarter of a pixel from the gap between the fields, on both pages. */
    margin-top: 7px;
}
@media (max-width: 614px) {
    #uks-billing-address #uks-address-element {
        width: 100%;
    }
}
/* end of 71.5 */

/* ==========================================================================
   71.6 (S238 ADDR-d, Rob, the 28th of September 2026: "put a small notice at the top saying something like: 'This is
   Stripe's own form, your details go straight to them' or whatever version of that is actually true"). The note above
   Stripe's billing address fields (functions.php 7.3.5.3d, span#uks-address-note.form-hint) is the checkout's own note:
   the postcode and date of birth notes' class and values, read on the live checkout at 1280 ("Nunito Sans" 12px,
   weight 400, line-height 19.2px, rgba(3, 27, 131, 0.75), centred; from .uks-page-shell .form-hint above and the shell's
   own face and centring). On the Registration card box it sits in the row's flex column, so the row's own 6px gap
   stands between the label, the note and the first field, as between the postcode row's label, field and note: the
   12px ADDR-c put on the mount point to hold the label 21px over the first field is replaced by that rhythm now the
   note stands between them. /billing/ has no .uks-page-shell around the form, so the same values are named here, and
   the same 6px stands between the note and the first field: PMPro's .pmpro_form_fields wrapper (a flex column with its
   own 18px gap, measured) holds only the note and Stripe's field in this card, so its gap takes the row's 6px. The card
   title's own 16px above the note is left as built (Rob chooses between that and 3.5px more by eye).
   ========================================================================== */
body.pmpro-billing #uks-billing-address .pmpro_form_fields {
    gap: 6px;
}
body.pmpro-billing #uks-billing-address .form-hint {
    display: block;
    margin: 0;
    font-family: var(--font-body);
    font-size: 12px;
    font-weight: 400;
    line-height: 1.6;
    color: var(--color-text-secondary);
    text-align: center;
}
/* end of 71.6 */

/* ==========================================================================
   72. SECTION: The inherited body face (S227, T-S224-013 second half)

   Rob (T-S224-013): "whatever that incorrect font was, you need to grep the rest
   of the visible user-facing platform and make sure it's not being used elsewhere."

   The parent theme leaves <body> on its own stack, headed by a face this site
   never loads:
       Muli, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
       "Helvetica Neue", Arial, sans-serif
   Every element that declares no family of its own inherits it, so it paints in
   whichever fallback the device happens to have (Segoe UI on Windows, Arial on
   Linux) rather than in the brand body face. Measured S227: 268 such elements
   across 20 member-facing page loads, the heaviest being the member-card
   "Active / a minute ago" line, the Messages bubble text, thread previews and
   times, and the workspace subtitle that heads five member pages.

   The rule being replaced is the first rule of
   wp-content/uploads/custom_styles/seeko-dynamic.css, which the Seeko theme
   generates from its options panel and enqueues AFTER this file. A plain 'body'
   selector therefore loses to it on source order; 'html body' does not. Measured
   S227 against the live stylesheet: plain 'body' moved nothing, 'html body' took
   every element probed on six surfaces.

   NOTE: this declaration is visually inert until the brand webfonts are actually
   enqueued on the platform. Measured S227: neither Montserrat nor Nunito Sans is
   loaded on any member page, so both the old value and the new one fall back to
   the same system face today. See HANDOFFS_FOR_LOOSE_ENDS.md, the functions.php
   enqueue hunk, which is the other half of this fix.
   ========================================================================== */
html body {
    font-family: var(--font-body);
}

/* 72.1 The same generated file also sets `.blockquote, blockquote` to 'Fira Sans',
   a face only ever loaded here as an italic-only Google embed that no rule asks for.
   A direct declaration on the element beats an inherited one whatever its specificity,
   so the body rule above cannot reach it and this second declaration is required.
   The one member-facing blockquote is the venue quote card on the single event page
   (event-page.css 4.11.1 to 4.11.5), which is body copy, so it takes the body face.
   The decorative gold quotation glyph keeps its Georgia serif: that is deliberate
   (event-page.css 4.11.2) and is not touched. */
html .blockquote,
html blockquote {
    font-family: var(--font-body);
}
/* end of 72 */

/* =========================================================================
   S229 16/09/26: A BUTTON THAT HAS BEEN CHOSEN IS PRESSED IN, SO IT LOSES ITS SHADOW
   Rob (T-S229-032, repeated on the host register): "any button that's been pressed and
   selected and turned on, so to speak, and is highlighted permanently because it's been
   chosen, should lose the drop shadow." One rule for every selected state the platform
   already uses; nothing else about those states changes.
   ========================================================================= */
.btn-option--select.active,
.btn-option.is-selected,
.btn-option[aria-pressed="true"],
.wishlist-button.wishlist-active:not(:where(.vw-owner-msg)),
.dropdown__option.is-selected,
.selection-bar__btn.is-selected,
.pickable-pill.is-selected,
.interest-btn-active {
  box-shadow: none !important;
}

/* S229 16/09/26 (T-S229-061), Rob with his own profile picture: "the dashboard and profile and
   customize buttons that show up under the sigil all need to be changed just like the login and
   dashboard buttons in the top right of each page were changed so they need to go to the normal
   light cream background go border, blue text styling like the download button." */
#buddypress .profile-header-actions .generic-button a,
.profile-header-actions .generic-button a {
  background: var(--color-cream, #FFFBE6) !important;
  background-image: none !important;
  border: 2px solid var(--color-gold, #CC9900) !important;
  color: var(--color-navy, #031B83) !important;
}
#buddypress .profile-header-actions .generic-button a:hover,
.profile-header-actions .generic-button a:hover {
  background: var(--color-cream-hover, #FFF6CC) !important;
  color: var(--color-navy, #031B83) !important;
  border-color: var(--color-gold, #CC9900) !important;
}

/* S229 16/09/26 (T-S213-024 g), Rob: the Affiliate tab's "How it works" card is left aligned
   and should be centred. It stays centred (every line below), but the lists no longer carry their markers inside the centred line.
   S245 row 89 (Rob, the 7th of October 2026, on the same card: "The starts of each paragraph there are in bold. At least it's centered, but that makes no sense. It's a
   really odd format. If it's a subtitle, make it a subtitle and add some gold spaces and stuff. Make it neat or something. Like you already know all the styling rules.").
   The bold lead of the opening paragraph, of each of the four steps and of each of the six rules is now a SUBTITLE on its own line, and a gold spacer sits between one block
   and the next. Every value below is one Rob has already signed off, nothing is new:
   - the subtitle is the dashboard card title (.workspace .card__title, 42.4: Montserrat 700, 18px, navy) with the title treatment's gold rule under it that hugs the words and
     centres (.host-register__title and the PANEL-1 refund panel title, event-page.css 11.14: display table, fit-content, margin-inline auto, 2px solid gold), 6px of room
     above the rule as the event page's sub-heading has it (.event-description h3, event-page.css 5.9.7), a 1.3 line for a title that wraps (.wl-card__title, page-polish.css, the wish
     list card title); the title's drop shadow is left off because Rob asked for it on titles and it would smear 18px type;
   - the gold spacer is the host register's divider between one name and the next (event-page.css 11.14: 282px wide, 1px, --color-gold, centred, never wider than its card);
   - one gap (--sp-lg, 16px) sits under each subtitle's rule and above and below each spacer, and the lists' and items' own margins are stood down, so no gap can drift (the
     PANEL-1 and cancel panel rhythm, page-polish.css 55: one gap, nothing else);
   - the step numbers keep the old li::marker's look (Montserrat, bold, gold) but are a counter at the front of the subtitle now, so each number sits on its subtitle's line
     and under its gold rule instead of floating inside a centred paragraph.
   The page's own inline style (mu-plugins/uksocials-affiliate-tab.php 3.4.8) sets margins, padding-left 24px (which, with the marker inside, put the four steps up to 22.9px
   right of the card's centre line, measured at 1280 and at 360), the rules list's border-top and the font sizes on .aff-workspace .aff-intro, .aff-steps and .aff-rules at
   specificity (0,2,0), and it comes later in the page than this file, so these selectors carry .workspace.aff-workspace (the same element, two classes) to outrank it. This
   replaces the S229 rules (.aff-intro, .aff-steps and .aff-rules centred, marker inside). */
.workspace.aff-workspace .aff-intro,
.workspace.aff-workspace .aff-steps,
.workspace.aff-workspace .aff-rules { text-align: center; }
.workspace.aff-workspace .aff-intro { margin: 0; }
.workspace.aff-workspace .aff-steps { margin: 0; padding: 0; list-style: none; counter-reset: aff-step; }
.workspace.aff-workspace .aff-steps > li { margin: 0; padding: 0; counter-increment: aff-step; }
.workspace.aff-workspace .aff-rules { margin: 0; padding: 0; border-top: 0; }
.workspace.aff-workspace .aff-rules > li { margin: 0; padding: 0; }
.workspace.aff-workspace .aff-steps > li::before,
.workspace.aff-workspace .aff-rules > li::before {
  content: "";
  display: block;
  width: 282px;
  max-width: 100%;
  height: 1px;
  margin: var(--sp-lg) auto;
  background: var(--color-gold);
}
.workspace.aff-workspace .aff-intro > strong:first-child,
.workspace.aff-workspace .aff-steps > li > strong:first-child,
.workspace.aff-workspace .aff-rules > li > strong:first-child {
  display: table;
  width: fit-content;
  max-width: 100%;
  margin: 0 auto var(--sp-lg);
  padding-bottom: 6px;
  border-bottom: 2px solid var(--color-gold);
  font-family: var(--font-heading);
  font-size: 18px;
  font-weight: 700;
  line-height: 1.3;
  color: var(--color-navy);
}
.workspace.aff-workspace .aff-steps > li > strong:first-child::before {
  content: counter(aff-step) ". ";
  color: var(--color-gold);
}


/* ============================================================================
   S231 18/09/26 - THE MAIN PAGE TITLES TAKE THE EVENT PAGE'S TITLE TREATMENT
   Rob: "all the main title pages, like events, venues, members, etcetera, should all have the drop
   shadow and gold underline spacer, like on the event pages." The shadow and the rule are copied
   from .event-card__title (event-page.css 5.6) exactly; the size is left alone because he asked for
   the shadow and the underline, not a resize. display:table plus auto margins makes the gold rule
   hug the words and centre, the same way it does on the event page.
   Scoped to body.page so it reaches the WordPress pages (Events, Venues, Organisers, Members,
   Pricing and the rest) and never the single event, which has its own title already.
   ============================================================================ */
body.page .entry-title.page-title,
body.directory .entry-title.page-title,
body.blog .entry-title.page-title,
body.page-id-3727 h1.uksp-heading-title,
body.page-id-439 h1.uksp-heading-title {
    /* 26/09 (Rob, with five screenshots): the Blog, Pricing and Contact titles join this rule so every main page carries
       the same gold underline; the space below every title is set to the Events page's in 11.11 further down. */
    color: var(--color-navy);
    text-shadow: 0 4px 6px rgba(3,27,131,.18), 0 2px 4px rgba(3,27,131,.12);
    /* the parent theme sets a width on .page-title with !important, so the underline ran the full
       header width instead of hugging the words; these two are the only declarations that need to
       beat it. */
    display: table !important;
    width: fit-content !important;
    max-width: 100%;
    margin-left: auto;
    margin-right: auto;
    padding-bottom: 8px;
    border-bottom: 2px solid var(--color-gold);
}

/* S231 18/09/26 (triage item 79, the emoji sweep): the dashboard week-nav arrows and the gallery
   empty-state picture were the typographic characters and the picture emoji. Both are brand
   drawings now. The arrow takes the button's own colour and sits on the label's centre line. */
.week-nav__btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
.uks-navarrow { display: block; flex: 0 0 auto; }
.gal-empty__icon .uks-empty-glyph { display: block; margin-inline: auto; }

/* S231 18/09/26, Rob: the Featured Events pill label "is still low". MEASURED by painted ink: the
   label sat 0.25px BELOW the pill centre, and the 21px From Your List sat 0.25px above it, so one
   padding value could never serve both. The label is now wrapped and moved by transform, per pill
   size, and it lands where he likes a cap-only label: half a pixel high. */
.dash-title-label {
  display: inline-block;
  transform: translateY(-0.75px);
}
#list-heading .dash-title-label {
  transform: translateY(-0.25px);
}


/* ============================================================================
   R3-35b 25/09/26 - BLOG POSTS: GOLD ACCENTS, GLOBAL AT THE POST TEMPLATE (item 35 follow-up)
   Rob, on the post he was shown: "Verified fixed, but add some more colour ... gold spaces ...
   make some of the text gold ... global across every blog." Item 35's history: the earlier
   fixes were made per post instead of at the template, which is why they vanished. Everything
   below sits on the post template (article.standard-post), never inside a post, so it reaches
   every post automatically. Body copy stays navy; the title keeps its own shadow and colour as
   fixed under item 35 (h1.entry-title is untouched here).
   ============================================================================ */

/* R3-35b.1 Subheadings inside the post body, gold. */
article.standard-post .entry-content-inner h2,
article.standard-post .entry-content-inner h3 {
    color: var(--color-gold);
}

/* R3-35b.1a BLOG-2 (Rob, 28/09/2026: "The subtitle here shouldn't be bigger than the main title!?
   Check this on all blog pages as that is just weird."). The headings inside a post body had no
   size of their own: the parent theme's generated stylesheet (seeko-dynamic.css, h1 and h2 at 3.157
   and 2.369rem from 1150px up) drew the subtitle at 56.8px and every section heading at 42.6px in
   Fira Sans 500, the SAME size as the 56.8px post title (functions.php, globalsocials-brand-css)
   and far above the brand scale. Every post opens its body with an h1 subtitle, then h2 sections.
   They now step DOWN from the title at every width, on the brand guide's heading scale (3.3:
   h1 32/26/22, h2 24/22/20, h3 20/18/17, with its line heights), in the site heading face and the
   weight of the title and of every other section heading on the site (Montserrat 600,
   functions.php "Section headings within pages"). h4 to h6 share one step below h3 so no deeper
   heading can outgrow it. Colours are not set here: the subtitle stays navy and h2/h3 stay gold
   (R3-35b.1). The margins stay the theme's. Scoped to the post body, so the title, the /blog/
   cards and every other page keep their own headings. */
article.standard-post .entry-content-inner :is(h1, h2, h3, h4, h5, h6) {
    font-family: var(--font-heading, 'Montserrat', sans-serif);
    font-weight: 600;
}
article.standard-post .entry-content-inner h1 { font-size: 32px; line-height: 1.2; }
article.standard-post .entry-content-inner h2 { font-size: 24px; line-height: 1.25; }
article.standard-post .entry-content-inner h3 { font-size: 20px; line-height: 1.3; }
article.standard-post .entry-content-inner :is(h4, h5, h6) { font-size: 18px; line-height: 1.3; }
@media (max-width: 1023px) {
    article.standard-post .entry-content-inner h1 { font-size: 26px; }
    article.standard-post .entry-content-inner h2 { font-size: 22px; }
    article.standard-post .entry-content-inner h3 { font-size: 18px; }
    article.standard-post .entry-content-inner :is(h4, h5, h6) { font-size: 17px; }
}
@media (max-width: 600px) {
    article.standard-post .entry-content-inner h1 { font-size: 22px; }
    article.standard-post .entry-content-inner h2 { font-size: 20px; }
    article.standard-post .entry-content-inner h3 { font-size: 17px; }
    article.standard-post .entry-content-inner :is(h4, h5, h6) { font-size: 16px; }
}

/* R3-35b.2 A gold hairline above every h2 in the body: 1px tall, 48px wide, before the heading's
   own text. One rule, one place.
   BLOG-1 (Rob, 28/09/2026: "They should be between the paragraphs if anything", then "Centre them
   between the sections"): the line sat at the far left of the column (margin 32px 0 16px). It is
   centred now: margin-left and margin-right auto put its midpoint on the column midpoint. And it
   sits half way between the sections: measured by painted ink, the paragraph above ended 35.5 to
   41.5px above the line and the heading ink began 19.5 to 23.75px below it (360 to 1920), because
   the theme's 2rem top margin on a heading after a paragraph collapses with the 32px here.
   A translateY moves the painted line, and only the line, to the middle of that space; whole pixels
   so the 1px line stays sharp. No box moves, so the heading and every paragraph keep their places.
   The size of the nudge at each width is BLOG-3's, below. */
article.standard-post .entry-content-inner h2::before {
    content: "";
    display: block;
    width: 48px;
    height: 1px;
    margin: 32px auto 16px;
    transform: translateY(-11px);
    background: var(--color-gold);
}
/* BLOG-3 (S238, the 29th of September 2026), replacing the BLOG-1 and BLOG-2 nudges (9px, and 8px under 601px). The two
   gaps are measured between what the eye takes as the edges of the text: the BASELINE of the paragraph's last line
   above (its tails hang below that) and the TOP OF THE CAPITALS of the heading below. Measured so on live, on all six
   headings of a post, the line stood nearer the heading at every width: by 4.75px at 1920, 4.4 at 1280, 2.0 at 1024,
   3.2 at 768, 3.7 at 600 and 3.4 at 360. The space either side of the line changes with the page's text size (the
   theme's root size is 18px from 1150px up, 17px from 768px, 16px below) and with the heading's size (24, 22 and 20px,
   R3-35b.1a), so there is one nudge for each of the five combinations, whole pixels so the 1px line stays sharp.
   MEASURED AFTER, the mean of the six headings, the gap below less the gap above: -0.76px (1920), -0.43 (1280),
   0.03 (1100 and 1024), 0.83 (768), -0.97 (700), 0.27 (600), 0.63 (360). No box moves: only the line is painted higher. */
@media (max-width: 1149px) {
    article.standard-post .entry-content-inner h2::before {
        transform: translateY(-10px);
    }
}
@media (max-width: 1023px) {
    article.standard-post .entry-content-inner h2::before {
        transform: translateY(-11px);
    }
}
@media (max-width: 767px) {
    article.standard-post .entry-content-inner h2::before {
        transform: translateY(-9px);
    }
}
@media (max-width: 600px) {
    article.standard-post .entry-content-inner h2::before {
        transform: translateY(-10px);
    }
}

/* R3-35b.3 The post meta line (date and author). Measured live: the theme's generated
   stylesheet (seeko-dynamic.css, enqueued after this file) sets .standard-post-meta .author-name
   to #333 and .standard-post-meta .entry-date to #9a9a9a, both specificity (0,2,0); named
   directly here at (0,3,1) so this wins on specificity, not on load order. */
article.standard-post .standard-post-meta .author-name,
article.standard-post .standard-post-meta .entry-date {
    color: var(--color-gold);
}

/* R3-35b.4 Blockquotes. Measured live: the theme's generated stylesheet already puts a 4px
   gold left border on every blockquote with black text (`.blockquote,blockquote`); the post
   body wants 3px and navy, named directly here so this wins on specificity. */
article.standard-post .entry-content-inner blockquote {
    border-left: 3px solid var(--color-gold);
    color: var(--color-navy);
}

/* R3-35b.5 Body links: gold, no underline at rest, gold underline on hover. Measured live:
   Section 67.9 (28/06/26) sets `a:hover, a:focus { text-decoration: none !important; }`
   site-wide, deliberately !important so nothing beats it on specificity (Rob 28/06/26: the
   default underline-on-hover "looks wrong site-wide; suppress it everywhere"). That rule is
   correct for buttons and UI chrome and stays exactly as it is for the rest of the platform.
   This brief (R3-35b, 25/09/26) explicitly asks for the opposite inside blog post body copy: a
   gold underline on hover. Matched here with an equally deliberate, narrowly scoped !important
   so this one content area can state its own exception without touching Section 67.9. */
/* S245 item S9-60 (list 16 September item 60, T-S213-014 "Cream like the rest", the event series dates). This rule is the blog post's own body link style, but its
   selector reaches every link inside any article.standard-post, and the single event page is one: MEASURED live on /events/example-family-park-games-morning/, a series
   date pill hovered paints a GOLD label with a gold underline (the pill's own rule in event-system.php, color #031B83 and text-decoration none, loses to this one at 0,2,2
   against 0,1,2). The pills now yield to their own rule, which already draws the canonical hover: darker cream #FFF5CC, navy label, gold ring, no underline. The
   exclusion sits in :where() so the rule's specificity is unchanged for every blog link. Other links on the event page that this rule also colours gold are left alone. */
/* S245 recaptures-s229 (registry rows T-S229-052 and T-S229-028: restyle the category tag exactly like the 16-17 tag). This blog body-link rule reaches the single event page
   too, because the event page is the same article.standard-post, and it turned the clickable category pill's label gold (rgb(204,153,0),
   cascade read live: this rule at (0,2,2) beats .event-badges .event-age-pill at (0,2,0), which sets navy). The pill is a link that is a pill, not
   body copy, so it is left out of this rule by its own class; :where() keeps the specificity of the rule exactly as it was for every other link. */
article.standard-post .entry-content-inner a:where(:not(.single-event-series-dates__list a)):where(:not(.event-age-pill)) {
    color: var(--color-gold);
    text-decoration: none;
}
article.standard-post .entry-content-inner a:where(:not(.single-event-series-dates__list a)):where(:not(.event-age-pill)):hover {
    color: var(--color-gold);
    text-decoration: underline !important;
    text-decoration-color: var(--color-gold) !important;
}
/* end of R3-35b */

/* R3-33c (item 33, Rob 25/09/2026, his ruling on Option A / Option B): "It actually needs to be
   both. It needs to show the venue and the description, but the venue doesn't need to be the
   whole address ... Just one clickable link for the venue. You can gain height by having the
   report and show interest buttons on the same row side by side ... still centred as a
   combination ... move the show interest down to the same row as the report and then move the
   detailed panel currently is on in option A and then you can move the description to where the
   information panel currently is." The EVENT card only: name -> venue link -> description ->
   the fact panel -> the button row (event-system.php 10.2/10.1a.4). Venue, organiser and member
   cards pass none of the new render() keys this needs, so their markup and their CSS are
   untouched (Rule 13).

   3. THE VENUE LINK reuses .uks-card__meta ("the one line under the name"), which already goes
   navy at rest and gold on hover for every link on the card family (52.3's .uks-card__meta a
   rule), so it needs no colour of its own here. Only its HEIGHT differs on the event card: one
   line, not the three-line description block venue, organiser and member cards put there
   (52.3's height:50.4px stands for them unchanged; this is a more specific selector, not a
   second rule on the same one). */
[data-uks-card="event"] .uks-card__meta {
    height: 16.8px;
}

/* 4. THE DESCRIPTION is a new block, the event's own short description (or, with none written
   yet, the first sentence of its full description, clipped - event-system.php 10.1a.3j, the
   same helper the venue and organiser cards already call for theirs). It takes the exact
   three-line box 52.3 already measured for that same job (12px/1.4, three lines, 50.4px,
   overflow hidden) so an event card reads the same way venue and organiser cards do. It prints
   only when the event card passes desc_html; no other caller does, so .uks-card__desc never
   appears on another card type. */
.uks-card__desc {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    line-height: 1.4;
    color: var(--navy75);
    height: 50.4px;
    overflow: hidden;
}

/* 5. THE FACT PANEL (DATE / STARTS / PRICE) moves into .uks-card__foot on the event card
   (facts_in_foot in the render call), so no new CSS is needed for it: .uks-card__facts is
   already width:100% and self-contained, and .uks-card__foot already gives its children the
   same var(--step) gap .uks-card__body used to.

   6. THE BUTTON ROW. Section 66 (S222, Rob 14/09/26) stacks .uks-card__actions under 600px for
   every card type, which still stands for venues, organisers and members; the event card alone
   stays in the row it already uses above 600px - grid-auto-flow:column, the fit-content box
   centred by margin-left/right:auto, the two 1fr tracks that size both buttons to the wider one
   (52.4, item 225) - because that row already puts an equal gap either side of the pair for
   free. Nothing below is a new value; it is the base (>600px) rule's own values, reused. */
@media (max-width: 599.98px) {
    [data-uks-card="event"] .uks-card__actions {
        grid-auto-flow: column;
    }
    [data-uks-card="event"] .uks-card__actions .uks-card__btn {
        width: 100%;
    }
}
/* end of R3-33c */

/* R3-33c GATE 12 (25/09/2026): the Show Interest / Report label is not centred BY INK inside its
   own button - MEASURED live (getBoundingClientRect + the gate's own dpr-8 capital-to-baseline
   read) at 0.703px HIGH, with height:40px and an already-symmetric 7px/7px padding (so flex
   align-items:center is centring the LINE BOX correctly; the residual is Montserrat Bold's own
   ascent/descent not bracketing its cap-height/baseline symmetrically at this size, the same
   family of defect page-polish.css already corrects elsewhere, e.g. the age-pill hyphen at
   52.3/.uks-card__age-sep). Pre-existing on every card type (measured identically stacked and in
   a row, before this item touched anything), not introduced here; fixed here, scoped to the card
   family's own action buttons, because GATE 12 refuses to compose a picture of it uncorrected.
   Redistributing the button's own vertical padding by the measured amount moves the centred
   content by exactly that amount inside the fixed 40px box (the same mechanism already proven at
   .uks-card__fact's 9px/9px, 52.3) without moving the button's own border. */
.uks-card__actions .uks-card__btn {
    padding-top: 7.7px !important;
    padding-bottom: 6.3px !important;
}
