@charset "UTF-8";
/* ==========================================================================================
   Lake Miramichi POA - design system

   Direction: the current Wix site's deep navy + lake photography identity is genuinely good and
   recognisable, so it is kept. What is dropped is the execution - the oval-outline logo, ALL CAPS
   body copy, cards floating unreadably on busy foliage, default Arial, and large dead areas of empty
   colour. This aims at "a small association that takes itself seriously", not a template.

   Everything is self-hosted: no CDN, no webfont service, no framework. That keeps the Content
   Security Policy strict and means the site works if the machine has no internet egress.
   ========================================================================================== */

:root {
    /* Brand navy, sampled from the existing site and extended into a usable scale. */
    --navy-900: #072338;
    --navy-800: #0a2f4a;
    --navy-700: #0e3a5a;
    --navy-600: #14496f;
    --navy-500: #1d5d8a;
    --navy-100: #e8eef4;

    /* Lake accent - a muted teal that reads as water without being a "tech" cyan. */
    --teal-600: #16697a;
    --teal-500: #1d8298;

    /* Autumn accent, borrowed from the hero photography. Used sparingly, for emphasis only. */
    --amber-600: #b26a1f;
    --amber-500: #d98324;

    --ink-900: #14202b;
    --ink-700: #33475b;
    --ink-500: #5b6b7c;
    --ink-300: #93a1ae;

    --paper: #ffffff;
    --paper-tint: #f6f8fa;
    --line: #dfe5ea;

    --danger: #a4262c;
    --ok: #1c6b45;

    --radius: 10px;
    --radius-sm: 6px;
    --shadow-sm: 0 1px 2px rgba(7, 35, 56, .06), 0 1px 3px rgba(7, 35, 56, .08);
    --shadow-md: 0 4px 12px rgba(7, 35, 56, .10), 0 2px 4px rgba(7, 35, 56, .06);
    --shadow-lg: 0 12px 32px rgba(7, 35, 56, .16);

    /* One spacing scale, used everywhere. Consistent rhythm is most of what "professional" means. */
    --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px; --s5: 24px;
    --s6: 32px; --s7: 48px; --s8: 64px; --s9: 96px;

    --measure: 68ch;          /* readable line length for body copy */
    --page: 1180px;           /* content column */
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    background: var(--paper);
    color: var(--ink-900);
    /* System stack: fast, no external request, and looks native on Windows, macOS and phones. */
    font-family: "Segoe UI", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
    font-size: 17px;
    line-height: 1.65;
    -webkit-font-smoothing: antialiased;
}

/* ── Typography ─────────────────────────────────────────────────────────────────────────── */
h1, h2, h3, h4 {
    margin: 0 0 var(--s4);
    line-height: 1.2;
    color: var(--navy-800);
    font-weight: 650;
    letter-spacing: -0.015em;
}
h1 { font-size: clamp(2rem, 4.2vw, 3rem); }
h2 { font-size: clamp(1.5rem, 2.6vw, 2.05rem); }
h3 { font-size: 1.25rem; }
h4 { font-size: 1.05rem; }

p { margin: 0 0 var(--s4); max-width: var(--measure); }
a { color: var(--teal-600); text-decoration: underline; text-underline-offset: 2px; }
a:hover { color: var(--navy-700); }

.lede { font-size: 1.15rem; color: var(--ink-700); max-width: 60ch; }
.eyebrow {
    text-transform: uppercase; letter-spacing: .14em; font-size: .75rem;
    font-weight: 700; color: var(--teal-600); margin-bottom: var(--s2);
}
.muted { color: var(--ink-500); }
.small { font-size: .875rem; }

/* Accessibility: a visible focus ring everywhere, never removed. */
:focus-visible { outline: 3px solid var(--amber-500); outline-offset: 2px; border-radius: 3px; }

.skip-link {
    position: absolute; left: -9999px; top: 0; background: var(--navy-800); color: #fff;
    padding: var(--s3) var(--s4); z-index: 200;
}
.skip-link:focus { left: var(--s4); top: var(--s4); }

/* ── Layout ─────────────────────────────────────────────────────────────────────────────── */
.page { width: min(var(--page), calc(100% - 2 * var(--s5))); margin-inline: auto; }
.section { padding-block: var(--s8); }
.section--tint { background: var(--paper-tint); border-block: 1px solid var(--line); }
.stack > * + * { margin-top: var(--s4); }

.grid { display: grid; gap: var(--s5); }
@media (min-width: 700px)  { .grid--2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 940px)  { .grid--3 { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 940px)  { .grid--4 { grid-template-columns: repeat(4, 1fr); } }
@media (min-width: 940px)  { .grid--sidebar { grid-template-columns: 1fr 300px; gap: var(--s7); } }

/* ── Header / navigation ────────────────────────────────────────────────────────────────── */
.masthead {
    background: var(--navy-800);
    color: #fff;
    position: sticky; top: 0; z-index: 100;
    box-shadow: var(--shadow-md);
}
.masthead__inner {
    display: flex; align-items: center; gap: var(--s5);
    min-height: 68px;
}
.brand { display: flex; align-items: center; gap: var(--s3); text-decoration: none; color: #fff; }
.brand__mark {
    width: 38px; height: 38px; flex: none; border-radius: 8px;
    background: linear-gradient(150deg, var(--teal-500), var(--navy-600));
    display: grid; place-items: center; font-weight: 700; font-size: .95rem; letter-spacing: -.02em;
}
.brand__name { font-weight: 650; font-size: 1.06rem; letter-spacing: -.01em; line-height: 1.15; white-space: nowrap; }
/* The association's full name is long. Keep it on one line and let it disappear on narrow screens
   rather than wrapping the masthead into four lines. */
.brand__sub { display: block; font-weight: 400; font-size: .7rem; color: #a9c3d6; letter-spacing: .01em; white-space: nowrap; }
@media (max-width: 1100px) { .brand__sub { display: none; } }

/* The nav is generated from the area registry, so its length is DATA, not a fixed design decision -
   Travis can add a section whenever he likes. With nine public areas plus the sign-in button it
   already measured 1175px against ~1004px of available space at a 1440px window, pushing the whole
   PAGE into a horizontal scroll (measured: scrollWidth 1596 vs clientWidth 1425).

   So the nav must survive an arbitrary number of items. Two rules do that:
     * wrap onto a second row rather than overflow - a taller header is fine, a sideways-scrolling
       page is not;
     * min-width: 0 so the flex item is actually allowed to shrink below its content width. Without
       it, a flex child refuses to go under max-content and overflows regardless of wrapping.
   The hamburger breakpoint below is also raised, so on mid-size screens the menu collapses before
   the items get a chance to collide. */
.nav {
    margin-left: auto; display: flex; align-items: center; gap: var(--s1);
    flex-wrap: wrap; justify-content: flex-end; min-width: 0; row-gap: 4px;
}

/* ── "More" overflow menu ────────────────────────────────────────────────────────────────────
   A <details> element, so it works with no JavaScript at all. The panel is absolutely positioned
   so opening it never changes the header's height and never nudges the page. */
.nav__more { position: relative; }
.nav__more > summary {
    list-style: none; cursor: pointer;
    color: #d7e4ee; padding: var(--s2) 8px; border-radius: var(--radius-sm);
    font-size: .92rem; white-space: nowrap; user-select: none;
}
.nav__more > summary::-webkit-details-marker { display: none; }   /* Safari's default triangle */
.nav__more > summary::after {
    content: ""; display: inline-block; margin-left: 6px; vertical-align: 2px;
    border: 4px solid transparent; border-top-color: currentColor;
}
.nav__more > summary:hover { background: rgba(255,255,255,.10); color: #fff; }
.nav__more[open] > summary { background: rgba(255,255,255,.14); color: #fff; }
.nav__more-panel {
    position: absolute; right: 0; top: calc(100% + 6px); z-index: 120;
    min-width: 220px; display: flex; flex-direction: column;
    background: var(--navy-800); border: 1px solid rgba(255,255,255,.12);
    border-radius: var(--radius); box-shadow: var(--shadow-lg); padding: var(--s2);
}
.nav__more-panel a { display: block; }
.nav a {
    color: #d7e4ee; text-decoration: none; padding: var(--s2) 6px;   /* 8px -> 6px to make room for search */
    border-radius: var(--radius-sm); font-size: .92rem; white-space: nowrap;
}
.nav a:hover { background: rgba(255,255,255,.10); color: #fff; }
.nav a[aria-current="page"] { color: #fff; background: rgba(255,255,255,.14); font-weight: 600; }

/* Travis 2026-08-26: "the upper right login box is below the links at the top it can get moved over to
   the right next to those links maybe a bit smaller". It was being pushed onto a second row by the
   wrapping nav, so it is now smaller AND the row is given enough slack to keep it alongside the links:
   the inline section count drops to five (see _Layout) and the link padding tightens a little. */
.nav__cta {
    margin-left: var(--s2); background: var(--amber-500) !important; color: var(--navy-900) !important;
    font-weight: 650; font-size: .85rem !important; padding: 5px var(--s3) !important;
    flex: none;
}
.nav__cta:hover { background: var(--amber-600) !important; color: #fff !important; }

.nav-toggle {
    margin-left: auto; display: none; background: transparent; border: 1px solid rgba(255,255,255,.3);
    color: #fff; border-radius: var(--radius-sm); padding: 6px 10px; font-size: 1rem; cursor: pointer;
}
/* Raised from 900px to 1150px: the horizontal nav genuinely stops fitting well before 900px once the
   area registry has this many public sections, so the hamburger has to take over sooner. */
@media (max-width: 1150px) {
    .nav-toggle { display: block; }
    .nav {
        display: none; position: absolute; inset-inline: 0; top: 100%;
        flex-direction: column; align-items: stretch; gap: 0; flex-wrap: nowrap;
        background: var(--navy-800); padding: var(--s3); box-shadow: var(--shadow-lg);
    }
    .nav.is-open { display: flex; }
    .nav a { padding: var(--s3) var(--s4); }
    .nav__cta { margin: var(--s2) 0 0; text-align: center; }

    /* Inside the mobile drawer the drawer IS the menu, so flatten "More" open rather than making
       someone tap twice to reach a section. */
    .nav__more { position: static; }
    .nav__more > summary { display: none; }
    .nav__more-panel {
        position: static; min-width: 0; background: none; border: 0;
        box-shadow: none; padding: 0; border-radius: 0;
    }
}

/* ── Hero ───────────────────────────────────────────────────────────────────────────────── */
/* The old site put light text straight onto autumn foliage, which is unreadable. Here the photo sits
   under a navy gradient scrim so the type always has contrast, whatever image is chosen. */
.hero { position: relative; background: var(--navy-900); color: #fff; overflow: hidden; }
.hero__media { position: absolute; inset: 0; }
.hero__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hero__scrim {
    position: absolute; inset: 0;
    background:
        linear-gradient(180deg, rgba(7,35,56,.72) 0%, rgba(7,35,56,.55) 45%, rgba(7,35,56,.88) 100%);
}
.hero__inner { position: relative; padding-block: var(--s9); }
.hero h1 { color: #fff; max-width: 22ch; }
.hero .lede { color: #d9e6f0; }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--s3); margin-top: var(--s5); }

/* ── Cards ──────────────────────────────────────────────────────────────────────────────── */
.card {
    background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius);
    padding: var(--s5); box-shadow: var(--shadow-sm);
    display: flex; flex-direction: column;
}
.card h3 { margin-bottom: var(--s2); }
.card p { margin-bottom: var(--s3); }
.card__foot { margin-top: auto; padding-top: var(--s3); }

/* A notice card - the "board meeting notice" pattern from the old site, done legibly. */
.notice {
    border-left: 4px solid var(--amber-500);
    background: #fffaf2; border-radius: var(--radius-sm);
    padding: var(--s4) var(--s5);
}
.notice--info { border-left-color: var(--teal-500); background: #f2f9fb; }

/* Tile: the LMPOA hub's icon grid */
.tile {
    display: flex; align-items: flex-start; gap: var(--s3);
    padding: var(--s4); border: 1px solid var(--line); border-radius: var(--radius);
    background: var(--paper); text-decoration: none; color: inherit;
    transition: box-shadow .15s ease, transform .15s ease, border-color .15s ease;
}
.tile:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); border-color: var(--navy-100); }
.tile__icon {
    flex: none; width: 40px; height: 40px; border-radius: 9px;
    background: var(--navy-100); color: var(--navy-700);
    display: grid; place-items: center; font-size: 1.15rem;
}
.tile__title { display: block; font-weight: 650; color: var(--navy-800); line-height: 1.3; }
.tile__desc { display: block; font-size: .85rem; color: var(--ink-500); margin-top: 2px; }

/* ── Buttons ────────────────────────────────────────────────────────────────────────────── */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
    padding: 11px var(--s5); border-radius: var(--radius-sm); border: 1px solid transparent;
    font: inherit; font-weight: 600; text-decoration: none; cursor: pointer;
    transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.btn--primary { background: var(--navy-700); color: #fff; }
.btn--primary:hover { background: var(--navy-800); color: #fff; }
.btn--accent { background: var(--amber-500); color: var(--navy-900); }
.btn--accent:hover { background: var(--amber-600); color: #fff; }
/* >>> GHOST IS FOR A LIGHT PAGE FIRST. <<<
   This used to be white text on a translucent white border - which is legible ONLY on the navy hero.
   Every other use of it is on a white page, so 110 buttons across 42 pages were white-on-white:
   present in the markup, measurable in the DOM, and completely invisible to a person. That is why
   "no cancel button again" and "i dont see any add button" kept coming back - the button was there
   every time. Light is now the default; the white version is scoped to the dark blocks that need it. */
.btn--ghost { background: var(--paper); border-color: var(--line); color: var(--navy-700); }
.btn--ghost:hover { background: var(--paper-tint); border-color: var(--navy-500); color: var(--navy-800); }
.hero .btn--ghost, .footer .btn--ghost, .site-header .btn--ghost, .nav .btn--ghost {
    background: transparent; border-color: rgba(255,255,255,.45); color: #fff;
}
.hero .btn--ghost:hover, .footer .btn--ghost:hover, .site-header .btn--ghost:hover,
.nav .btn--ghost:hover { background: rgba(255,255,255,.12); border-color: rgba(255,255,255,.7); color: #fff; }
/* >>> A THIRD ACTION NEEDS A THIRD LOOK. <<<
   Travis 2026-09-01: *"can we make this button a different color so it doesnt plend in with the rest
   Request website access"*. In the hero it sat in ghost white beside "Forms & requests", so the two
   read as one pair and the important one disappeared. The hierarchy now goes amber (sign in) - lake
   (request access) - outline (browse the forms).

   TWO GROUNDS, TWO TREATMENTS. Teal on a white page is a clear filled button. Teal on the HERO would
   sink into a photograph of a lake, so there it goes solid white on navy text - which no other button
   in the hero uses, and a photograph cannot swallow. */
.btn--lake { background: var(--teal-600); color: #fff; border-color: var(--teal-600); }
.btn--lake:hover { background: var(--teal-500); color: #fff; border-color: var(--teal-500); }
.hero .btn--lake, .footer .btn--lake { background: #fff; color: var(--navy-900); border-color: #fff; }
.hero .btn--lake:hover, .footer .btn--lake:hover { background: var(--amber-500); color: var(--navy-900); border-color: var(--amber-500); }

.btn--quiet { background: var(--paper); border-color: var(--line); color: var(--navy-700); }
.btn--quiet:hover { background: var(--paper-tint); }
.btn--danger { background: var(--danger); color: #fff; }
/* >>> DONE IS GREEN, NOT-DONE IS RED. <<< Travis 2026-09-01: *"the mark as dealth with should be a green
   button as its done, then put back on the list should be red as nope its not done put it back on the
   list"*. --ok already existed for exactly this reading; nothing had used it as a button. */
.btn--ok { background: var(--ok); color: #fff; border-color: var(--ok); }
.btn--ok:hover { background: #17573a; color: #fff; border-color: #17573a; }
/* >>> RED, BUT NOT THE SAME RED AS DELETE. <<< "Put back on the list" sits directly beside "Delete this
   entry". Painted the same solid red, the reversible one and the permanent one were indistinguishable at
   a glance - and the permanent one cannot be undone. Same colour, hollow, so the meaning Travis asked
   for survives and the destructive button is still the only solid red on the row. */
.btn--undo { background: var(--paper); color: var(--danger); border-color: var(--danger); }
.btn--undo:hover { background: #fdf3f3; color: var(--danger); border-color: var(--danger); }
.btn--sm { padding: 6px var(--s3); font-size: .875rem; }
.btn[disabled] { opacity: .5; cursor: not-allowed; }

/* ── Forms ──────────────────────────────────────────────────────────────────────────────── */
.field { margin-bottom: var(--s4); }
.field label { display: block; font-weight: 600; font-size: .9rem; margin-bottom: 6px; color: var(--ink-700); }
.field .help { font-size: .82rem; color: var(--ink-500); margin-top: 5px; }
.req { color: var(--danger); }

/* >>> input:not([type]) MATTERS. <<< A bare <input> has no type attribute, so it matches none of the
   attribute selectors below and falls back to the browser's own tiny grey box - visibly different from
   every styled field beside it. 60 inputs across the site were rendering that way, which is what made
   the agenda rows look like a loose pile rather than a form. */
input:not([type]), input[type=text], input[type=email], input[type=password], input[type=tel],
input[type=number], input[type=date], input[type=time], input[type=search], input[type=file],
select, textarea {
    width: 100%; padding: 10px var(--s3); font: inherit; color: var(--ink-900);
    background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-sm);
}
textarea { min-height: 120px; resize: vertical; }
input:focus, select:focus, textarea:focus { border-color: var(--teal-500); }
.checks label { display: flex; align-items: flex-start; gap: var(--s2); font-weight: 400; margin-bottom: 6px; }
.checks input { width: auto; }

.form-card { background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius); padding: var(--s6); box-shadow: var(--shadow-sm); }
.form-actions { display: flex; gap: var(--s3); align-items: center; margin-top: var(--s5); }

.alert { padding: var(--s3) var(--s4); border-radius: var(--radius-sm); margin-bottom: var(--s4); border: 1px solid; }
.alert--error { background: #fdf3f3; border-color: #f0c7c7; color: #7d1d22; }
.alert--ok    { background: #f1f9f4; border-color: #c3e3d0; color: #14543a; }
.alert--info  { background: #f2f9fb; border-color: #c9e3ea; color: #14515e; }

/* ── Tables (documents, submissions, admin lists) ───────────────────────────────────────── */
.table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); background: var(--paper); }
table.data { width: 100%; border-collapse: collapse; font-size: .93rem; }
table.data th {
    text-align: left; padding: var(--s3) var(--s4); background: var(--paper-tint);
    border-bottom: 1px solid var(--line); font-size: .78rem; text-transform: uppercase;
    letter-spacing: .07em; color: var(--ink-500);
}
table.data td { padding: var(--s3) var(--s4); border-bottom: 1px solid var(--line); vertical-align: middle; }
table.data tr:last-child td { border-bottom: 0; }
table.data tbody tr:hover { background: #fbfcfd; }

.badge {
    display: inline-block; padding: 2px 9px; border-radius: 999px; font-size: .75rem; font-weight: 650;
    background: var(--navy-100); color: var(--navy-700);
}
.badge--ok { background: #e4f3ea; color: var(--ok); }
.badge--warn { background: #fdf1e2; color: var(--amber-600); }
.badge--quiet { background: #eef1f4; color: var(--ink-500); }

/* Empty states: an area with no content yet should explain itself, not look broken. */
.empty {
    text-align: center; padding: var(--s8) var(--s5); color: var(--ink-500);
    border: 1px dashed var(--line); border-radius: var(--radius); background: var(--paper-tint);
}
.empty h3 { color: var(--ink-700); }

/* ── Footer ─────────────────────────────────────────────────────────────────────────────── */
/* No top margin: every preceding section already carries its own bottom padding, and adding to it
   left a large empty band - the exact flaw the old site had. */
.footer { background: var(--navy-900); color: #b9cddc; padding-block: var(--s7) var(--s5); }
.footer h4 { color: #fff; font-size: .8rem; text-transform: uppercase; letter-spacing: .12em; margin-bottom: var(--s3); }
.footer a { color: #cfe0ec; text-decoration: none; }
.footer a:hover { color: #fff; text-decoration: underline; }
.footer ul { list-style: none; margin: 0; padding: 0; }
.footer li { margin-bottom: 7px; }
.footer__bar {
    margin-top: var(--s6); padding-top: var(--s4); border-top: 1px solid rgba(255,255,255,.12);
    display: flex; flex-wrap: wrap; gap: var(--s3); justify-content: space-between;
    font-size: .82rem; color: #8fa9bd;
}

/* ── Print: minutes and financials get printed, so make that not look broken ────────────── */
@media print {
    .masthead, .footer, .nav, .hero__media, .hero__scrim, .btn { display: none !important; }
    body { font-size: 11pt; }
    a { text-decoration: none; color: #000; }
}

/* ── Document lists ─────────────────────────────────────────────────────────────────────────
   Minutes, financials, newsletters, reports. The whole row is the target rather than just the
   title, because most of these are opened on a phone and a small text link is a poor tap target -
   44px minimum, which is Apple's own guidance and about the width of an adult fingertip. */
.doclist { list-style: none; margin: var(--s4) 0 0; padding: 0; }
.doclist__item + .doclist__item { border-top: 1px solid var(--line); }
.doclist__link {
    display: flex; align-items: center; gap: var(--s4);
    padding: var(--s4) var(--s2); min-height: 44px;
    text-decoration: none; color: inherit; border-radius: var(--radius-sm);
}
.doclist__link:hover { background: var(--paper-tint); }
.doclist__icon {
    flex: none; width: 40px; height: 40px; border-radius: 8px;
    display: grid; place-items: center;
    background: var(--navy-100); color: var(--navy-600);
    font-size: .62rem; font-weight: 700; letter-spacing: .06em;
}
.doclist__body { display: flex; flex-direction: column; min-width: 0; }
.doclist__title { font-weight: 600; color: var(--navy-800); }
.doclist__meta { font-size: .82rem; color: var(--ink-500); }

/* ── PDF viewer ─────────────────────────────────────────────────────────────────────────────
   The embed is the browser's own viewer. It is HIDDEN below 820px because iOS Safari and Android
   Chrome frequently render an empty box instead of the PDF - so on a phone the buttons above are
   the route, handing off to the phone's own viewer, which handles pinch-zoom and sharing properly. */
.doc__actions { display: flex; flex-wrap: wrap; gap: var(--s3); margin-block: var(--s5) var(--s2); }
.doc__hint { margin-bottom: var(--s5); }
.doc__viewer { display: none; }
.doc__frame {
    width: 100%; height: min(80vh, 900px); border: 1px solid var(--line);
    border-radius: var(--radius); background: var(--paper-tint);
}
@media (min-width: 820px) {
    .doc__viewer { display: block; }
    .doc__hint { display: none; }
}

/* ── Long-form content written in the admin editor ──────────────────────────────────────────── */
.prose { max-width: var(--measure); }
.prose h2 { margin-top: var(--s7); }
.prose h3 { margin-top: var(--s6); }
.prose ul, .prose ol { padding-left: var(--s5); }
.prose li + li { margin-top: var(--s2); }
.prose img { max-width: 100%; height: auto; border-radius: var(--radius); }
.prose table { width: 100%; border-collapse: collapse; }
.prose td, .prose th { border: 1px solid var(--line); padding: var(--s2) var(--s3); text-align: left; }

/* ── People (board, committees) ─────────────────────────────────────────────────────────────── */
.person__name { margin-bottom: 2px; font-size: 1.1rem; }
.person__role {
    margin: 0 0 var(--s3); font-size: .78rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: .1em; color: var(--teal-600);
}

/* ── Small status tags ──────────────────────────────────────────────────────────────────────── */
.tag {
    display: inline-block; padding: 1px 7px; border-radius: 999px;
    font-size: .7rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
    background: var(--navy-100); color: var(--navy-600);
}
.tag--warn { background: #fdf2e2; color: var(--amber-600); }

/* ── Data tables ────────────────────────────────────────────────────────────────────────────
   Paired overflow-x with overflow-y: hidden. overflow-x alone creates a second scroller and the
   page ends up with two scrollbars fighting each other. */
table.data { width: 100%; border-collapse: collapse; margin-block: var(--s4); font-size: .93rem; }
table.data th, table.data td {
    border-bottom: 1px solid var(--line); padding: var(--s3); text-align: left; vertical-align: top;
}
table.data thead th {
    font-size: .72rem; text-transform: uppercase; letter-spacing: .08em;
    color: var(--ink-500); border-bottom: 2px solid var(--line);
}
table.data tbody tr:hover { background: var(--paper-tint); }
table.data .row--emphasis { background: var(--paper-tint); }

.btn--danger { background: var(--danger); color: #fff; border-color: var(--danger); }
.btn--danger:hover { background: #8a1f24; color: #fff; }

/* ── Admin list furniture ───────────────────────────────────────────────────────────────────── */
.stat { font-size: 2rem; font-weight: 650; margin: 0; line-height: 1.1; color: var(--navy-800); }
.filterbar {
    display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--s3);
    padding: var(--s4); margin-block: var(--s5);
    background: var(--paper-tint); border: 1px solid var(--line); border-radius: var(--radius);
}
.field--inline { margin: 0; }
.field--inline label { display: block; font-size: .78rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: .06em; color: var(--ink-500); margin-bottom: 2px; }
.field--inline input, .field--inline select { min-width: 150px; }

/* Compact inline form used in admin tables (status change on a row). */
.inline-form { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.inline-form select, .inline-form input { min-width: 0; width: auto; max-width: 130px; }

/* ── Board candidates ────────────────────────────────────────────────────────────────────────── */
.candidate { display: flex; gap: var(--s5); align-items: flex-start; margin-bottom: var(--s5); }
.candidate__photo {
    flex: none; width: 132px; height: 132px; object-fit: cover;
    border-radius: var(--radius); background: var(--navy-100);
}
.candidate__name { margin-bottom: var(--s2); font-size: 1.25rem; }
/* pre-wrap keeps the candidate's own paragraph breaks without letting them inject markup. */
/* >>> pre-wrap KEEPS THE LINE BREAKS BUT WILL NOT BREAK A WORD. <<< Travis 2026-09-02: *"the test
   persons little saying about there selfs doesn't stay in the box the letters go right past the box
   line across the page"*. His test text was one unbroken run of "blahblah..." - pre-wrap respects the
   newlines somebody typed, which is why it is here, but a single word longer than the card has
   nowhere to wrap and rides straight out of it. anywhere lets it break mid-word as a last resort,
   and min-width:0 stops it forcing the flex card wider than its column.
   A real biography never hits this. A pasted URL does, and so does anybody testing. */
.candidate__statement { white-space: pre-wrap; margin: 0; overflow-wrap: anywhere; min-width: 0; }
@media (max-width: 640px) {
    .candidate { flex-direction: column; }
    .candidate__photo { width: 100%; height: 220px; }
}

/* Submission cards */
.sub__head { display: flex; flex-wrap: wrap; gap: var(--s3); justify-content: space-between; align-items: flex-start; }
.subfiles { display: flex; flex-wrap: wrap; gap: var(--s4); margin-top: var(--s3); }
.subfile { width: 160px; }
.subfile img { width: 160px; height: 120px; object-fit: cover; border-radius: var(--radius-sm); border: 1px solid var(--line); }
.subfile__doc {
    display: grid; place-items: center; width: 160px; height: 120px;
    background: var(--navy-100); color: var(--navy-600); border-radius: var(--radius-sm);
    font-weight: 700; font-size: .8rem; letter-spacing: .06em; text-decoration: none;
}

.person__photo {
    /* >>> THE FRAME MUST MATCH THE SOURCE'S SHAPE. <<<
       These are square face crops (Wix's own framing, which the board chose). Forcing them into a
       width:100% / height:190px box is a WIDE frame, so object-fit:cover threw away the top and bottom
       of a square picture - which is the head. A square frame crops nothing at all.
       object-position stays as insurance for any photo added later that is not square. */
    width: 100%; aspect-ratio: 1 / 1; height: auto;
    object-fit: cover; object-position: center top;
    border-radius: var(--radius-sm); margin-bottom: var(--s3); background: var(--navy-100);
}
/* ══════════════════════════════════════════════════════════════════════════════════════════════
   >>> A BIOGRAPHY WITH NO SPACES IN IT WRECKED THIS WHOLE PAGE. <<<

   Travis 2026-09-02: *"go right now and look at the board of directors page after clicking add the
   winners to the board its pretty messed up"*. It was. Two pushed members had unbroken runs of text
   in their biographies, nothing could wrap them, so their grid column stretched to about 3,000px -
   which made the page scroll sideways AND squeezed every other column to 105px. David Crown's card
   became a sliver with his biography one word per line and the card 2,114px tall.

   This is the same bug as `.candidate__statement` on the ballot, which I fixed a day earlier and
   never carried across to here. A real biography would not do it; a pasted URL will.

   min-width:0 matters as much as the wrap: without it a grid item refuses to shrink below its
   longest word, which is what let one card push all the others aside.
   ══════════════════════════════════════════════════════════════════════════════════════════════ */
.person, .person * { min-width: 0; }
.person p, .person__bio, .person__name, .person__role, .person__contact {
    overflow-wrap: anywhere;
}

.person__term { margin-top: -6px; margin-bottom: var(--s3); }

/* ── Photo gallery ───────────────────────────────────────────────────────────────────────────── */
.album { display: flex; flex-direction: column; text-decoration: none; color: inherit; }
.album:hover { box-shadow: var(--shadow-md); }
.album__cover {
    width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
    border-radius: var(--radius-sm); margin-bottom: var(--s3); background: var(--navy-100);
}
.album__title { font-weight: 650; color: var(--navy-800); }
.album__meta { font-size: .82rem; color: var(--ink-500); }
.photos { display: grid; gap: var(--s4); grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
.photo img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: var(--radius-sm); background: var(--navy-100); }
.photo__caption { font-size: .82rem; color: var(--ink-500); margin-top: 4px; }
.photo__doc {
    display: grid; place-items: center; width: 100%; aspect-ratio: 4 / 3;
    background: var(--navy-100); color: var(--navy-600); border-radius: var(--radius-sm);
    font-weight: 700; font-size: .78rem; text-decoration: none; text-align: center; padding: var(--s3);
}

/* On-this-page jump list.
   Added automatically to any imported page with four or more top-level sections. The bylaws page is
   three documents and nearly 12,000 words - without this, finding Article V on a phone means scrolling
   past everything before it. */
.page-toc {
    margin: 0 0 var(--s6);
    padding: var(--s4) var(--s5);
    background: var(--paper-tint);
    border: 1px solid var(--line);
    border-radius: var(--radius);
}
.page-toc > p { margin: 0 0 var(--s2); font-size: .9rem; color: var(--ink-600); }
.page-toc ul { margin: 0; padding-left: var(--s5); }
.page-toc li { margin: 0 0 2px; font-size: .95rem; }
.page-toc a { text-decoration: none; }
.page-toc a:hover, .page-toc a:focus-visible { text-decoration: underline; }

/* A heading landed on from the jump list should not sit flush against the viewport edge. */
.page h2[id] { scroll-margin-top: var(--s5); }

/* >>> THE MASTHEAD IS STICKY, SO SOMETHING SCROLLED TO CAN END UP BEHIND IT. <<<
   Travis 2026-09-02, arriving on the ballot: *"the item is partially hidden by the header bar i have to
   scroll up right away to see the item"*. The cause was a stale saved scroll position (fixed in
   site.js), but any anchor, any Back-button restore and any focus scroll can do the same thing. This
   tells the browser to leave the header's height clear whenever IT does the scrolling. */
html { scroll-padding-top: 84px; }
.topic, .pick, .notice { scroll-margin-top: 84px; }

/* Two or more columns once there is room, because thirteen entries is a long thin list on a desktop. */
@media (min-width: 700px) {
    .page-toc ul { columns: 2; column-gap: var(--s6); }
}

/* A list with no bullet, used for committee rosters. */
ul.plain { list-style: none; margin: 0; padding: 0; }
ul.plain li { padding: 3px 0; border-bottom: 1px solid var(--line); }
ul.plain li:last-child { border-bottom: 0; }

/* Pictures inside page content. Imported from the old site, so their natural sizes vary wildly -
   980px banners next to 358px thumbnails - and they must never push the page sideways on a phone. */
.prose img { max-width: 100%; height: auto; border-radius: var(--radius-sm); display: block; }
.prose p:has(> img) { margin: var(--s5) 0; }

/* A document that has a picture of itself - the subdivision maps. The picture is the link, so the map
   you want is one tap away instead of a scroll past all the others. */
.doccard {
    display: flex; flex-direction: column; text-decoration: none; color: inherit;
    border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden;
    background: var(--paper); transition: box-shadow .15s ease, border-color .15s ease;
}
.doccard:hover, .doccard:focus-visible { box-shadow: var(--shadow-md); border-color: var(--teal-500); }
.doccard img {
    width: 100%; aspect-ratio: 4 / 3; object-fit: cover; object-position: center top;
    display: block; background: var(--navy-100);
}
.doccard__nothumb {
    display: flex; align-items: center; justify-content: center;
    aspect-ratio: 4 / 3; background: var(--paper-tint); color: var(--ink-600);
    font-size: .8rem; letter-spacing: .08em;
}
.doccard__title { padding: var(--s3) var(--s4) 0; font-weight: 600; }
.doccard__note { padding: 2px var(--s4) var(--s4); font-size: .85rem; color: var(--ink-600); }

/* A table imported from page content - the Projects list.
   >>> ITS OWN CLASS, NOT THE ADMIN ".data" ONE. <<<
   Reusing the admin table class dragged in a grey header band and cell borders, so a page a reader is
   scanning looked like a spreadsheet being operated. Travis: "the table for the other projects is a bit
   squshed up". Rules here, and nothing inherited. */
.table-scroll { overflow-x: auto; margin: var(--s6) 0; }
.content-table {
    width: 100%; border-collapse: collapse; font-size: .95rem; line-height: 1.5;
    /* >>> min-width: 40rem WAS HERE, AND IT WAS THE BUG. <<<
       It was set so a status like "Scheduled to start in spring" stayed on one line. 40rem is 640px and
       the reading column is 623px, so the table overflowed by 17 pixels and scrolled sideways on a
       1400px screen - Travis: "adjust the grid so there is no scroll on computer, probably will be one
       on the phone". Keeping a phrase on one line is not worth a scrollbar on every desktop. The cells
       wrap instead, and .table-scroll still rescues genuinely narrow screens. */
}
.content-table th {
    text-align: left; font-size: .72rem; text-transform: uppercase; letter-spacing: .09em;
    color: var(--ink-600); font-weight: 600; white-space: nowrap; background: none;
    padding: 0 var(--s6) 10px 0; border-bottom: 2px solid var(--line);
}
.content-table td {
    padding: 14px var(--s6) 14px 0; border: 0; border-bottom: 1px solid var(--line);
    vertical-align: top; background: none; white-space: normal;
}
/* The first column names the thing, so it carries the weight. */
.content-table td:first-child { font-weight: 600; }
.content-table th:last-child, .content-table td:last-child { padding-right: 0; }
.content-table tr:last-child td { border-bottom: 0; }

@media (max-width: 620px) {
    .content-table { font-size: .9rem; }
    .content-table th, .content-table td { padding-right: var(--s4); }
}

/* Events on the calendar. A date block beside the title, because an owner scanning for "when" reads the
   number first - not the sentence. */
.events { list-style: none; margin: 0; padding: 0; }
.event {
    display: flex; gap: var(--s5); align-items: flex-start;
    padding: var(--s4) 0; border-bottom: 1px solid var(--line);
}
.event:last-child { border-bottom: 0; }
.event__when {
    flex: 0 0 3.6rem; text-align: center; padding: 6px 0;
    border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--paper-tint);
}
.event__day { display: block; font-size: 1.45rem; font-weight: 700; line-height: 1;
              font-variant-numeric: tabular-nums; }
.event__mon { display: block; font-size: .7rem; text-transform: uppercase; letter-spacing: .08em;
              color: var(--ink-600); margin-top: 2px; }
.event__title { margin: 0 0 2px; font-size: 1.05rem; }
.event__meta { margin: 0; font-size: .88rem; color: var(--ink-600); }
/* Past events are kept for reference but should not compete with what is coming. */
.events--past .event { opacity: .65; }
.events--past .event__day { font-size: 1.15rem; }

/* ── Photograph grid and slideshow ──────────────────────────────────────────────────────────────── */
/* Thumbnails only in the grid: the album holds 119 pictures, and the full versions are fetched one at a
   time by the viewer. auto-fill keeps them a sensible size from a phone up to a desktop. */
.thumbs {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: var(--s3); margin: var(--s5) 0 0; padding: 0;
}
.thumb {
    padding: 0; border: 1px solid var(--line); border-radius: var(--radius-sm);
    background: var(--navy-100); cursor: pointer; overflow: hidden; display: block;
    transition: box-shadow .15s ease, transform .15s ease;
}
.thumb img { display: block; width: 100%; aspect-ratio: 1 / 1; object-fit: cover; }
.thumb:hover, .thumb:focus-visible { box-shadow: var(--shadow-md); transform: translateY(-2px); }

.lightbox {
    position: fixed; inset: 0; z-index: 100; display: flex; align-items: center;
    justify-content: center; gap: var(--s3); padding: var(--s4);
    /* Deliberately near-black in both themes: a photograph is judged against a neutral ground. */
    background: rgba(8, 12, 16, .93);
}
.lightbox[hidden] { display: none; }
.lb__figure { margin: 0; max-width: 100%; max-height: 100%; display: flex; flex-direction: column;
              align-items: center; gap: var(--s3); }
.lb__figure img {
    max-width: 100%; max-height: 82vh; width: auto; height: auto;
    border-radius: var(--radius-sm); background: #000;
}
.lb__figure figcaption { color: #e8eef0; font-size: .9rem; text-align: center; }
.lb__nav, .lb__close {
    border: 1px solid rgba(255, 255, 255, .3); background: rgba(255, 255, 255, .1); color: #fff;
    cursor: pointer; border-radius: 50%; line-height: 1; padding: 0;
}
.lb__nav { flex: 0 0 auto; width: 3rem; height: 3rem; font-size: 1.9rem; }
.lb__close { position: absolute; top: var(--s4); right: var(--s4); width: 2.6rem; height: 2.6rem;
             font-size: 1.6rem; }
.lb__nav:hover, .lb__close:hover { background: rgba(255, 255, 255, .22); }
.lb__nav:focus-visible, .lb__close:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

@media (max-width: 620px) {
    .thumbs { grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: var(--s2); }
    /* On a phone the arrows sit under the picture rather than squeezing it. */
    .lightbox { flex-wrap: wrap; }
    .lb__figure { order: -1; flex: 1 0 100%; }
    .lb__nav { width: 3.4rem; height: 3.4rem; }
}
@media (prefers-reduced-motion: reduce) {
    .thumb { transition: none; }
    .thumb:hover, .thumb:focus-visible { transform: none; }
}

/* A page's opening photograph, cropped to a strip.
   The homepage picture is nearly square, and full-height at the top of a page it pushed every word below
   the fold. Cropping is done here rather than to the file, so the original is untouched and a future
   wider photograph needs no re-cropping.
   object-position sits below centre: in these lake photographs the sky is the top third and the water is
   what people want to see. */
.prose img.page-banner {
    width: 100%; height: auto; aspect-ratio: 3.2 / 1; object-fit: cover; object-position: center 58%;
    border-radius: var(--radius-sm); display: block;
}
/* Wider crop on a phone would leave a letterbox sliver, so it gets taller as the screen narrows. */
@media (max-width: 760px) {
    .prose img.page-banner { aspect-ratio: 2.4 / 1; }
}
@media (max-width: 480px) {
    .prose img.page-banner { aspect-ratio: 1.9 / 1; }
}

/* Tile headings carried an inline style="margin:0" from the import. The visual editor strips inline
   styles - correctly, they are how a pasted Word document poisons a page - so the rule lives here now. */
.tile h3 { margin: 0 0 6px; font-size: 1.05rem; }
.tile p:last-child { margin-bottom: 0; }

/* ── Form builder ────────────────────────────────────────────────────────────────────────────────
   The questions are the thing being built, so they get the visual weight and the settings do not.
   A numbered list, because the order of a form is part of the form. */
.formbar { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 var(--s5); }
.qlist { list-style: none; counter-reset: q; margin: 0 0 var(--s6); padding: 0; }
.qitem { counter-increment: q; display: flex; gap: 14px; align-items: flex-start;
         padding: 12px 14px; border: 1px solid var(--line); border-radius: 8px;
         background: #fff; margin-bottom: 8px; }
.qitem::before { content: counter(q); flex: 0 0 26px; height: 26px; border-radius: 50%;
                 background: var(--navy-pale, #e8eef4); color: var(--navy, #0a2f4a);
                 font-size: .8rem; font-weight: 700; display: flex; align-items: center;
                 justify-content: center; margin-top: 2px; }
.qitem__main { flex: 1 1 auto; min-width: 0; }
.qitem__actions { display: flex; gap: 6px; align-items: flex-start; flex: 0 0 auto; }
.qitem__actions form { display: inline; }
.addq { margin-top: var(--s6); }
.moreq { margin: 0 0 var(--s4); }
.moreq > summary { cursor: pointer; font-size: var(--t-sm); color: var(--ink-soft, #5a6b78); }
.settings { margin-top: var(--s7); border-top: 1px solid var(--line); padding-top: var(--s4); }
.settings > summary { cursor: pointer; list-style: none; }
.settings > summary::-webkit-details-marker { display: none; }
.settings > summary h2 { display: inline; font-size: 1.15rem; }
/* marker comes from the shared .disclose rules at the end of this file */
.settings--danger > summary h2 { color: var(--bad, #a8342a); }
@media (max-width: 640px) {
    .qitem { flex-wrap: wrap; }
    .qitem__actions { width: 100%; justify-content: flex-end; }
}

/* Address field: five boxes that read as one address. Street and Line 2 take the full width; town,
   state and ZIP sit on one row, the way they are written on an envelope. */
.addr { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 10px; }
.addr .field--line1, .addr .field--line2 { grid-column: 1 / -1; }
.addr .field { margin: 0; }
.addr label.small { font-size: .78rem; color: var(--ink-soft, #5a6b78); }
@media (max-width: 520px) { .addr { grid-template-columns: 1fr; } }

/* A heading inside a form - a divider between parts of a long form, not a page title. */
.formsection { margin: var(--s6) 0 var(--s3); padding-top: var(--s4);
               border-top: 1px solid var(--line); font-size: 1.15rem; }
.formsection:first-child { border-top: 0; padding-top: 0; margin-top: 0; }

/* Lot number or street address - the choice first, then whichever half applies. */
.lotaddr__pick { display: flex; flex-wrap: wrap; gap: 18px; margin-bottom: 10px; }
.lotaddr__pick label { display: inline-flex; align-items: center; gap: 6px; margin: 0; }
.lotaddr .field { margin: 0; }

/* Owners-only marker on a tile - the homepage promises "sections marked Owners only need you to be
   signed in", so the mark has to actually exist. */
.tag--lock { font-size: .68rem; font-weight: 600; letter-spacing: .02em; text-transform: uppercase;
             background: #eef2f6; color: #45596b; border: 1px solid #d7dfe6;
             border-radius: 999px; padding: 2px 8px; margin-left: 8px; vertical-align: middle; }
.tile__count { margin: 6px 0 0; font-size: .78rem; color: var(--ink-soft, #5a6b78); }
a.card.tile h3 { margin: 0 0 6px; }

/* ── For Sale items ──────────────────────────────────────────────────────────────────────────────
   Travis: "right now its just picture blah blah blah picture blah blah blah picture.... can really tell
   them apart just runs on." Each item is one card: heading across the top, picture beside its details. */
.forsale-item { border: 1px solid var(--line); border-radius: 10px; background: #fff;
                padding: 18px 20px; margin: 0 0 var(--s5); }
.forsale-item > h2 { margin: 0 0 14px; font-size: 1.25rem; }
.forsale-item .item__media { float: right; width: 44%; margin: 0 0 12px 20px; }
.forsale-item .item__media img { width: 100%; height: auto; border-radius: 8px; display: block;
                                 margin-bottom: 10px; }
.forsale-item .item__body { overflow: hidden; }
.forsale-item .item__body > p { margin: 0 0 .45em; }
.forsale-item::after { content: ""; display: block; clear: both; }
@media (max-width: 620px) {
    .forsale-item .item__media { float: none; width: 100%; margin: 0 0 14px; }
}

/* ── A highlighted announcement inside page text ─────────────────────────────────────────────────
   "also highlight LMPOA now has a phone". */
.callout { border-left: 4px solid var(--accent, #d98324); background: #fdf6ec;
           border-radius: 0 8px 8px 0; padding: 16px 20px; margin: 0 0 var(--s5); }
.callout > h3 { margin: 0 0 8px; font-size: 1.15rem; }
.callout > p { margin: 0 0 .5em; }
.callout > p:last-child { margin-bottom: 0; }
.callout__big { font-size: 1.5rem; font-weight: 700; letter-spacing: .01em; }
.callout__big a { text-decoration: none; }



/* A single call to action at the top of a section - "Join a committee", "Add your photographs" -
   with the one line of context that would otherwise be buried below the list. */
.joinbar { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin: 0 0 var(--s5);
           padding: 14px 16px; border: 1px solid var(--line); border-radius: 10px; background: #f7f9fb; }
.joinbar .small { color: var(--ink-soft, #5a6b78); }

/* >>> A LIST OF CARDS IS NOT RUNNING TEXT, SO THE READING WIDTH DOES NOT APPLY. <<<
   Body text is capped at about 623px because that is where a line stops being comfortable to read. The
   For Sale items are cards with a photograph beside the details, and squeezed into that column the
   picture crowds the text while two thirds of a 1385px screen sits empty. :has lets the cap lift only
   for a prose block that actually contains cards. */
.prose:has(.forsale-item) { max-width: none; }
.prose:has(.forsale-item) > .page-toc { max-width: 62ch; }
@media (min-width: 900px) {
    .forsale-item .item__media { width: 34%; }
}

/* ── Breadcrumbs ─────────────────────────────────────────────────────────────────────────────────
   "Bread crumb navigation needed". Sits where the eyebrow line used to, so nothing shifts down. The
   current page is text, not a link. */
.crumbs { margin: 0 0 var(--s3); font-size: .8rem; letter-spacing: .02em; }
.crumbs ol { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0; }
.crumbs li { display: inline-flex; align-items: center; color: var(--ink-soft, #5a6b78); }
/* The separator is the literal character, NOT a CSS backslash-escape. Written as an escape it
   arrived as a control character followed by a stray "A" - a box and a letter between every
   crumb - because the backslash was eaten on the way into the file. */
.crumbs li + li::before { content: "›"; margin: 0 8px; color: #9fb0bd; }
.crumbs a { color: var(--ink-soft, #5a6b78); text-decoration: none; }
.crumbs a:hover { color: var(--navy, #0a2f4a); text-decoration: underline; }
.crumbs [aria-current="page"] { color: var(--navy, #0a2f4a); font-weight: 600; }
h1 .tag--lock { font-size: .58em; vertical-align: middle; }

/* ── Board voting ────────────────────────────────────────────────────────────────────────────────
   Topics are collapsed to a title for the same reason the incident list is: a board member opens the
   one that needs them rather than scrolling past ten full reports. */
.topic { border: 1px solid var(--line); border-radius: 10px; background: #fff; margin: 0 0 10px; }
.topic > summary { cursor: pointer; padding: 14px 18px; display: flex; flex-wrap: wrap;
                   gap: 4px 14px; align-items: baseline; }
.topic > summary::-webkit-details-marker { display: none; }
/* marker comes from the shared .disclose rules at the end of this file */
.topic__title { font-weight: 650; }
.topic__meta { font-size: .82rem; color: var(--ink-soft, #5a6b78); }
.topic--closed { background: #fbfcfd; }
/* >>> THE ONES STILL TO DEAL WITH HAVE TO BE FINDABLE AT A GLANCE. <<<
   Travis 2026-09-01: *"the ones that have not been dealt with yet should be a read or orange yellow
   color something so we are not looking thru a ton of submitted forms to find the one that needs to be
   dealth with"*. A whole page of identical white rows is what he was scanning.

   The amber runs down the LEFT EDGE and tints the row, so it is visible when the row is shut - which is
   how the list is now read - and it survives the row being opened. A tint alone is too weak to find by
   scrolling; a bar alone disappears at the top of a long list. */
.topic--todo { background: #fffaf0; border-color: #e8c98a; box-shadow: inset 4px 0 0 var(--amber-500); }
.topic--todo > summary { padding-left: 22px; }
.topic--todo > summary .topic__title { color: var(--navy-900); }
.topic__body { padding: 0 18px 18px; border-top: 1px solid var(--line); }
.topic__actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.topic__actions form { display: inline; }

.ballot { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; margin: 14px 0;
          padding: 14px 16px; border: 1px solid var(--line); border-radius: 8px; background: #f7f9fb; }
.ballot fieldset { border: 0; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 14px;
                   align-items: center; }
.ballot legend { padding: 0; margin-right: 10px; color: var(--ink-soft, #5a6b78); float: left; }
.ballot__opt { display: inline-flex; align-items: center; gap: 6px; }
.ballot input[name="note"] { flex: 1 1 200px; padding: 7px 10px; border: 1px solid #cdd2d8;
                             border-radius: 6px; font: inherit; }

.tally { width: 100%; border-collapse: collapse; margin: 10px 0 16px; }
.tally th { text-align: left; font-weight: 600; padding: 4px 10px 4px 0; white-space: nowrap; }
.tally__bar { width: 100%; }
.tally__bar span { display: block; height: 10px; border-radius: 5px; background: var(--navy-mid, #2b6a92);
                   min-width: 2px; }
.tally__n { width: 3ch; text-align: right; font-variant-numeric: tabular-nums; }

.votelist { list-style: none; margin: 0 0 8px; padding: 0; }
.votelist li { padding: 6px 0; border-bottom: 1px solid #eef1f4; }
.votelist li:last-child { border-bottom: 0; }
.log { margin-top: 12px; }
.log > summary { cursor: pointer; color: var(--ink-soft, #5a6b78); }
.report__topic { padding: 16px 0; border-bottom: 1px solid var(--line); }

/* A label/value list - contractor details, and anywhere else a handful of facts need reading down. */
.kv { display: grid; grid-template-columns: max-content 1fr; gap: 4px 18px; margin: 12px 0 4px; }
.kv dt { color: var(--ink-soft, #5a6b78); font-size: .85rem; }
.kv dd { margin: 0; }
@media (max-width: 520px) { .kv { grid-template-columns: 1fr; gap: 0 0; }
                            .kv dd { margin-bottom: 8px; } }

/* ── A document section with categories: year, then category, both collapsed ─────────────────────
   The newest year opens on arrival; the rest stay shut, because what somebody wants is nearly always
   the most recent thing. */
.docyear { border: 1px solid var(--line); border-radius: 10px; background: #fff; margin: 0 0 10px; }
.docyear > summary { cursor: pointer; padding: 14px 18px; display: flex; gap: 14px;
                     align-items: baseline; }
.docyear > summary::-webkit-details-marker { display: none; }
.docyear__title { font-weight: 650; font-size: 1.05rem; }
/* marker comes from the shared .disclose rules at the end of this file */
.doccat { padding: 0 18px 6px; }
.doccat h3 { font-size: .82rem; text-transform: uppercase; letter-spacing: .08em;
             color: var(--ink-600, #45596b); margin: 14px 0 6px; }
.doccat__n { font-weight: 400; color: #8fa3b3; margin-left: 6px; text-transform: none;
             letter-spacing: 0; }

.catlist { list-style: none; margin: 0 0 12px; padding: 0; }
.catlist li { display: flex; align-items: center; gap: 12px; padding: 7px 0;
              border-bottom: 1px solid #eef1f4; }
.catlist li span:first-child { font-weight: 600; min-width: 12ch; }
.catlist li form { margin-left: auto; }
.addcat { display: flex; gap: 8px; align-items: center; }
.addcat input { padding: 7px 10px; border: 1px solid #cdd2d8; border-radius: 6px; font: inherit; }

/* An expiry warning: not an error, but it needs to be noticed. */
.notice--warn { border-left-color: #d98324; background: #fdf6ec; }
.expiring { margin: 8px 0 0 18px; padding: 0; font-size: .9rem; }
.expiring li { margin: 2px 0; }

/* Recorded decisions - an email vote and the chain that proves it. */
.decisions { list-style: none; margin: 0; padding: 0; }
.decisions li { padding: 12px 0; border-bottom: 1px solid var(--line); }
.decisions li:last-child { border-bottom: 0; }
.decisions__head { display: flex; flex-wrap: wrap; gap: 10px; align-items: baseline; }
.decisions__head a { font-weight: 600; }

/* A collapsed settings panel can still show what it holds, so nothing has to be opened just to read it. */
.settings > summary .small { display: block; margin: 2px 0 0; }
.settings > summary h2 { margin-bottom: 0; }

/* ── The admin index ────────────────────────────────────────────────────────────────────────
   Thirty-four content tiles in one grid was a hunt. Two things fix it: headings that match the
   site's own menus, and a filter box. The headings do the work on their own, so the filter is
   an enhancement and starts hidden - see [data-admin-find] in site.js. */
.admin-h2 {
    margin-top: var(--s8); padding-bottom: 6px;
    border-bottom: 2px solid var(--navy-100);
}
.admin-h2__note { margin: 6px 0 var(--s5); font-size: .9rem; color: var(--ink-500); max-width: 62ch; }
.admin-h3 {
    margin: var(--s5) 0 var(--s3); font-size: 1rem; font-weight: 650;
    display: flex; flex-wrap: wrap; gap: 10px; align-items: baseline;
}
.admin-h3__note { font-size: .78rem; font-weight: 500; color: var(--ink-500); text-transform: none; letter-spacing: 0; }
.tag--off { background: #fdf2e2; color: var(--amber-600); margin-left: 6px; }

.admin-find { margin-top: var(--s6); }
.admin-find__label { display: block; font-size: .85rem; font-weight: 600; margin-bottom: 4px; }
.admin-find__input {
    width: 100%; max-width: 460px; padding: 9px 12px; font: inherit;
    border: 1px solid #cdd2d8; border-radius: 8px;
}
.admin-find__input:focus { outline: 2px solid var(--teal-500); outline-offset: 1px; border-color: var(--teal-500); }
.admin-find__none { margin: var(--s4) 0 0; font-weight: 600; color: var(--ink-500); }

/* A heading whose whole grid was filtered away must go too, or the page fills with empty headings. */
[data-admin-group][hidden], .admin-h2[hidden], .admin-h2__note[hidden] { display: none !important; }

/* ── A board member's headshot, on the roster admin ─────────────────────────────────────────
   The picture has to be visible next to its own controls: "replace the photograph" is a decision
   somebody makes by looking at the one that is there. */
.headshot {
    display: flex; gap: var(--s4); align-items: flex-start;
    margin-top: var(--s4); padding-top: var(--s4); border-top: 1px solid var(--line);
    flex-wrap: wrap;
}
.headshot__img {
    width: 96px; height: 96px; object-fit: cover; border-radius: 10px;
    border: 1px solid var(--line); display: block;
}
.headshot__none {
    width: 96px; height: 96px; border-radius: 10px; border: 1px dashed #cdd2d8;
    display: flex; align-items: center; justify-content: center;
    font-size: .78rem; color: var(--ink-500); text-align: center;
}
.headshot__controls { flex: 1 1 260px; min-width: 0; }
.headshot__controls .addcat { flex-wrap: wrap; }
.headshot__controls .help { margin-top: 6px; }

/* A tile plus its secondary link, as ONE grid cell. A bare <p> dropped into .grid becomes a grid item
   of its own and knocks the row out of line. */
.tile-cell { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.tile-cell > .tile { flex: 1 1 auto; }
.tile__alt { margin: 0; font-size: .78rem; }
.tile__alt a { color: var(--ink-500); }
.tile__alt a:hover { color: var(--navy-800); }

/* ── Per-member contribute rights, on the roster ────────────────────────────────────────────
   Thirty-four tick boxes need to be scannable, so they wrap in columns under their menu heading
   rather than running down the page in one long list. */
.rights__group {
    border: 1px solid var(--line); border-radius: 8px;
    padding: 8px 12px 10px; margin: 0 0 10px;
}
.rights__group legend {
    font-size: .78rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
    color: var(--ink-500); padding: 0 6px;
}
.rights__item {
    display: inline-flex; align-items: center; gap: 6px;
    width: 100%; font-size: .9rem; padding: 3px 0; font-weight: 400;
}
@media (min-width: 700px) { .rights__item { width: 48%; } }
@media (min-width: 1040px) { .rights__item { width: 32%; } }
.rights__item input { margin: 0; }
.rights > summary h2 { font-size: 1.05rem; }

/* ── The For Sale board ─────────────────────────────────────────────────────────────────────
   A classified advert is a photo, a price and a way to reach the seller. Sold items stay on the
   page, dimmed, because a seller wants to see their advert was there. */
.forsale { display: grid; gap: var(--s5); }
@media (min-width: 780px) { .forsale { grid-template-columns: repeat(2, 1fr); } }
.fs-item { display: flex; flex-direction: column; gap: var(--s3); }
.fs-item__photo {
    width: 100%; max-height: 260px; object-fit: cover;
    border-radius: 8px; border: 1px solid var(--line); display: block;
}
.fs-item__title { margin: 0; font-size: 1.1rem; display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; }
.fs-item__price { margin: 2px 0 0; font-weight: 700; color: var(--navy-800); }
.fs-item__desc { margin: 6px 0 0; white-space: pre-line; }
.fs-item__contact { margin: 8px 0 0; font-size: .92rem; }
.fs-item--sold { opacity: .62; }
.fs-item--sold .fs-item__photo { filter: grayscale(1); }
/* Admin list: a sold row should be obvious without reading. */
.card.is-sold { opacity: .72; }

/* An item's thumbnail in the admin list: landscape, because that is the shape of a boat, a jet ski and
   a lot. Clickable through to the full photograph so he never has to open the public page to check. */
.fs-thumb {
    width: 168px; height: 118px; object-fit: cover; display: block;
    border-radius: 8px; border: 1px solid var(--line); background: #f3f5f7;
}
.fs-thumb--none {
    display: flex; align-items: center; justify-content: center;
    border-style: dashed; border-color: #cdd2d8;
    font-size: .78rem; color: var(--ink-500);
}

/* ── The projects list ──────────────────────────────────────────────────────────────────────
   One card per project. Full width rather than a two-up grid: a project carries a description and
   an update note, and squeezing that into half a column makes both unreadable. */
.projlist { display: grid; gap: var(--s5); }
.proj { display: grid; gap: var(--s4); }
@media (min-width: 780px) { .proj { grid-template-columns: 260px 1fr; align-items: start; } }
.proj__photo {
    width: 100%; max-height: 200px; object-fit: cover;
    border-radius: 8px; border: 1px solid var(--line); display: block;
}
.proj__title { margin: 0 0 6px; font-size: 1.15rem; }
.proj__meta { margin: 0 0 8px; display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.proj__where { font-size: .88rem; color: var(--ink-500); }
.proj__desc { margin: 0 0 10px; white-space: pre-line; }
.proj__facts {
    display: grid; grid-template-columns: auto 1fr; gap: 2px 12px;
    margin: 0 0 10px; font-size: .9rem;
}
.proj__facts dt { font-weight: 650; color: var(--ink-500); }
.proj__facts dd { margin: 0; }
.proj__update {
    border-left: 3px solid var(--teal-500); background: #f2f9fb;
    padding: 8px 12px; border-radius: 0 6px 6px 0;
}
.proj__update p { margin: 4px 0 0; white-space: pre-line; }
.proj--done { opacity: .68; }
.proj--done .proj__photo { filter: grayscale(1); }


/* ── A collapsed row in the admin: projects, items for sale, anything list-shaped ─────────────────────────
   Seven full edit forms ran pages down the screen. The summary answers "which project and what state"
   so collapsing hides the FORM, never the information. Triangles are literal characters, not CSS
   escapes - an escape does not survive being written through a script. */
.itemrow > summary {
    cursor: pointer; list-style: none; padding: 4px 0;
    display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap;
}
.itemrow > summary::-webkit-details-marker { display: none; }
/* marker comes from the shared .disclose rules at the end of this file */
.itemrow > summary:hover .itemrow__title { text-decoration: underline; }
.itemrow__title { font-weight: 650; color: var(--navy-800); }
.itemrow__meta { font-size: .84rem; color: var(--ink-500); }
.itemrow__todo { color: var(--amber-600); font-weight: 600; }
.itemrow__body { margin-top: var(--s4); padding-top: var(--s4); border-top: 1px solid var(--line); }


/* A group band on the admin index. The h3 headings (Main menu, Documents, Rules, ...) were plain text
   between two grids, so a run of tiles had no visible start or end. A filled bar gives each group an
   edge you can see at a glance. */
.admin-h3 {
    background: var(--navy-100);
    border-left: 4px solid var(--navy-600);
    border-radius: 4px;
    padding: 7px 12px;
    margin: var(--s6) 0 var(--s4);
}
.admin-h3__note { color: var(--navy-600); }
/* And a rule under the group, so where it STOPS is as clear as where it starts. */
[data-admin-group] { padding-bottom: var(--s4); border-bottom: 1px dashed var(--line); }
[data-admin-group]:last-of-type { border-bottom: 0; }

/* The explanatory lists under a picker: what each choice actually means. Small, quiet, and always
   visible - a dropdown of seven menus tells you nothing about where any of them puts the page. */
.kindhelp { margin: 6px 0 0; padding-left: 18px; font-size: .8rem; color: var(--ink-500); }
.kindhelp li { margin: 2px 0; }

/* A vote outcome you can read without reading: green carried, red failed, amber could not count. */
.tag--good { background: #e4f3ea; color: var(--ok); }
.tag--bad  { background: #fdeceb; color: #a4262c; }

/* Any control that is still disabled must LOOK disabled. A greyed select that opens nothing reads as a
   bug, not as a read-only value - which is exactly how it was reported. */
input:disabled, select:disabled, textarea:disabled {
    background: #f1f3f5; color: #6b7680; cursor: not-allowed; border-color: #dde1e5;
}

/* A save at the TOP of a long section as well as the bottom. Three separate reports today came down to
   the same thing: the control existed and was below the fold. */
.savebar { margin: 0 0 var(--s3); }

/* The one save. Set apart, so it reads as the end of the editing rather than another button. */
.savebar--main {
    margin: var(--s6) 0 0; padding: var(--s4);
    background: var(--navy-100); border-radius: 8px;
    display: flex; gap: var(--s4); align-items: center; flex-wrap: wrap;
}


/* ── Agenda editor rows ─────────────────────────────────────────────────────────────────────
   One line of the agenda = one row: its number, its three boxes, its buttons. Every line is the
   same shape whether it is a section heading, a board member's name under Roll Call, or a note. */
.agrow {
    display: grid; grid-template-columns: 2.2rem minmax(0, 1fr) auto;
    gap: var(--s3); align-items: start;
    padding: var(--s3) var(--s3) var(--s3) 0; border-bottom: 1px solid var(--line);
}
.agrow:hover { background: var(--paper-tint); }
.agrow__num {
    text-align: right; padding-top: 10px; font-weight: 700; color: var(--navy-600);
    font-variant-numeric: tabular-nums; font-size: .95rem;
}
.agrow__main { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 1fr) minmax(0, 2fr) 9.5rem; gap: var(--s2); }
.agrow__main input { margin: 0; }
.agrow__acts { display: flex; gap: 6px; align-items: center; white-space: nowrap; padding-top: 2px; }
.agrow__acts .btn { padding: 6px 10px; }
.agrow__acts .agrow__move { padding: 6px 9px; font-size: 1rem; line-height: 1; }

/* A section heading sits proud of the lines beneath it, the way it reads on the printed agenda. */
.agrow--head { background: var(--navy-100); border-bottom-color: var(--navy-100); }
.agrow--head:hover { background: #dde7f0; }
.agrow--head .agrow__main input:first-child { font-weight: 700; color: var(--navy-800); }
/* A plain line is indented under its heading, and a note is indented further and italic. */
.agrow--item .agrow__main { margin-left: var(--s5); }
.agrow--note .agrow__main { margin-left: var(--s6); }
/* No italics, no grey, no special case: while editing, every line reads like every other line. */

.agadd {
    display: flex; flex-wrap: wrap; gap: var(--s3); align-items: end;
    margin-top: var(--s5); padding: var(--s4); border: 1px solid var(--line);
    border-radius: var(--radius-sm); background: var(--paper-tint);
}
.agadd .field { margin-bottom: 0; flex: 1 1 16rem; }
.agadd .field--kind { flex: 0 1 13rem; }
.agadd .field--where { flex: 1 1 20rem; }

/* >>> A NARROW ROW MUST STILL BE A ROW. <<<
   Travis: *"when i take my browser and shrink it as far as i can it doesn't really work"*. He was
   right, and the overflow check said nothing about it: the first version stacked all four boxes full
   width, so ONE agenda line took about 300px of screen and a 29-line agenda ran to 8,000px of
   scrolling. Nothing overflowed - it was simply unusable.

   So on a narrow screen the line keeps its shape: the title gets the full width because it is the
   one that matters, "who" and the kind share the next row, the note sits under them, and the padding
   comes in. That is about 185px a line instead of 300. */
@media (max-width: 900px) {
    .agrow {
        grid-template-columns: 1.6rem minmax(0, 1fr);
        padding: var(--s2) var(--s2) var(--s3) 0;
    }
    .agrow__num { padding-top: 8px; }
    .agrow__main {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        grid-template-areas: "title title" "who kind" "note note";
        gap: 6px;
    }
    .agrow__main > input[name=rowTitle] { grid-area: title; }
    .agrow__main > input[name=rowOwner] { grid-area: who; }
    .agrow__main > select[name=rowKind] { grid-area: kind; }
    .agrow__main > input[name=rowNote] { grid-area: note; }
    .agrow__main select { width: 100%; }
    .agrow__acts { grid-column: 2; flex-wrap: wrap; }
    .agrow--item .agrow__main, .agrow--note .agrow__main { margin-left: 0; }

    /* The boxes themselves come in, or three of them plus a button row is still a screenful. */
    .agrow input, .agrow select, .agrow textarea { padding: 8px var(--s2); }
    .agrow__acts .btn { padding: 8px 10px; min-height: 40px; }

    /* The minutes row is the same idea with the notes box taking the last full-width row. */
    .agrow__main--min {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        grid-template-areas: "title title" "who kind" "body body";
    }
    .agrow__main--min input[name=rowTitle] { grid-area: title; }
    .agrow__main--min input[name=rowOwner] { grid-area: who; }
    .agrow__main--min select { grid-area: kind; }
    .agrow__main--min textarea { grid-area: body; min-height: 4em; }

    /* Attendance: name wide, present/absent and title sharing the row under it. */
    .agrow__main--att {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        grid-template-areas: "name name" "state role";
    }
    .agrow__main--att input[name=attName] { grid-area: name; }
    .agrow__main--att select[name=attState] { grid-area: state; }
    .agrow__main--att input[name=attRole] { grid-area: role; }
}

/* On a phone, keep the two-column shape - "Dave" and a dropdown both fit inside 190px, and stacking
   them instead pushed a single agenda line to 324px, worse than what it replaced. What gives way is
   the BUTTON row: it wraps onto two lines, which costs 40px rather than 100. Measured 226px a line at
   390px wide, the same as at 768. */
@media (max-width: 520px) {
    .agrow { border-bottom-width: 2px; }
    .agrow__acts { gap: 5px; }
    .agrow__acts .btn { padding: 7px 9px; font-size: .82rem; min-height: 38px; }
    .agrow input, .agrow select, .agrow textarea { padding: 7px var(--s2); font-size: .95rem; }
}


/* ── Minutes editor rows ────────────────────────────────────────────────────────────────────────
   Same row shape as the agenda, but each line also has a notes box under it, so the boxes stack
   rather than sitting in one strip. Built narrow-first: a phone gets one column per box, which is the
   only thing that works at 390px, and the desktop layout is the enhancement. */
.agrow__main--min { grid-template-columns: minmax(0, 1fr); gap: var(--s2); }
.agrow__main--min textarea { min-height: 4.5em; font: inherit; line-height: 1.45; }
.agrow--min { align-items: start; }
.agrow__main--att { grid-template-columns: minmax(0, 1fr); gap: var(--s2); }

/* 901px, not 720: below that the narrow rules above own the layout, and two sets of grid-template
   -areas fighting over the same element is how a row ends up looking like a pile of boxes. */
@media (min-width: 901px) {
    .agrow__main--min {
        grid-template-columns: minmax(0, 3fr) minmax(0, 2fr) 9.5rem;
        grid-template-areas: "title owner kind" "body body body";
    }
    .agrow__main--min input[name=rowTitle] { grid-area: title; }
    .agrow__main--min input[name=rowOwner] { grid-area: owner; }
    .agrow__main--min select { grid-area: kind; }
    .agrow__main--min textarea { grid-area: body; }
    .agrow__main--att { grid-template-columns: minmax(0, 2fr) 10rem minmax(0, 2fr); }
}

/* Change requests from the board - the first thing on the screen when there are any. */
.changes { display: grid; gap: var(--s3); margin-bottom: var(--s5); }
.change {
    border-left: 4px solid var(--amber-500); background: var(--paper-tint);
    border-radius: var(--radius-sm); padding: var(--s3) var(--s4);
}
.change__who { margin: 0 0 4px; }
.change__text { margin: 0 0 var(--s3); white-space: pre-wrap; }
.approvals { margin: 0 0 var(--s4); padding-left: var(--s5); }
.approvals li + li { margin-top: var(--s2); }

/* ── The minutes, read as a document ───────────────────────────────────────────────────────────
   Reads like his Word minutes rather than a web page, and reflows to one column on a phone - a lot of
   the owners will only ever see this on a phone. */
.mins { max-width: 52rem; }
.mins__head { border-bottom: 3px solid var(--navy-700); padding-bottom: var(--s4); margin-bottom: var(--s5); }
.mins__assoc {
    margin: 0; font-size: .74rem; font-weight: 700; letter-spacing: .14em;
    text-transform: uppercase; color: var(--teal-600);
}
.mins__title { margin: 4px 0 var(--s4); font-size: clamp(1.5rem, 5vw, 2.1rem); line-height: 1.15; }
.mins__meta { display: grid; gap: var(--s3); margin: 0; grid-template-columns: 1fr; }
.mins__meta div { display: flex; gap: var(--s2); align-items: baseline; }
.mins__meta dt {
    margin: 0; font-size: .74rem; font-weight: 700; letter-spacing: .1em;
    text-transform: uppercase; color: var(--ink-500); min-width: 5.2em;
}
.mins__meta dd { margin: 0; font-weight: 600; }

.mins__h2 {
    margin: var(--s6) 0 var(--s2); padding-bottom: 4px;
    border-bottom: 1px solid var(--line); font-size: 1.12rem; color: var(--navy-800);
}
.mins__h3 { margin: var(--s4) 0 var(--s2); font-size: 1rem; color: var(--navy-700); }
.mins__who { display: block; font-size: .84rem; font-weight: 400; color: var(--ink-500); margin-top: 2px; }
.mins__note { margin: var(--s2) 0; color: var(--ink-500); font-style: italic; }
.mins__bul { margin: 0 0 var(--s3); padding-left: var(--s5); }
.mins__bul li { margin-top: 4px; }
.mins__bul li.sub { list-style: circle; margin-left: var(--s5); color: var(--ink-700); }
.mins__foot { margin-top: var(--s7); padding-top: var(--s3); border-top: 1px solid var(--line); color: var(--ink-500); }
.mins__foot p { margin: 0; font-size: .9rem; }
.mins__tools { margin-top: var(--s5); }

.mins__att { display: grid; gap: var(--s4); grid-template-columns: 1fr; }
.mins__att h3 {
    margin: 0 0 var(--s2); font-size: .8rem; font-weight: 700; letter-spacing: .08em;
    text-transform: uppercase; color: var(--ink-500);
}
.mins__att ul { margin: 0; padding-left: var(--s5); }

.approve {
    margin-top: var(--s7); padding: var(--s5); border: 1px solid var(--line);
    border-radius: var(--radius); background: var(--paper-tint);
}
.approve h2 { margin-top: 0; }
.approve__no { margin-top: var(--s4); }

@media (min-width: 620px) {
    .mins__meta { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .mins__att { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* Printing a set of minutes: paper, not screen furniture. */
@media print {
    .mins__tools, .approve, .crumbs, .notice { display: none !important; }
    .mins { max-width: none; }
    .mins__h2, .mins__h3 { break-after: avoid; }
    .mins__bul, .mins__att { break-inside: avoid; }
}

/* ── Phone: readable text and fingertip-sized controls ─────────────────────────────────────────
   Travis 2026-08-31: *"a ton of our users are only going to use there phone same with board"*.
   A 390px audit of 200 pages found no sideways scrolling and nothing overflowing, but plenty of
   9-11px text and controls 16-32px tall. A 22px inline link inside a paragraph is fine - that is
   text. A 32px MENU BUTTON is not. So: nothing under 12px anywhere, and every real control gets
   at least 44px of height to be tapped, which is the long-standing fingertip minimum. */
@media (max-width: 720px) {
    /* >>> A FLOOR, SO !important IS THE RIGHT TOOL. <<< Component rules are more specific than any
       list of classes here - `table.data thead th { font-size:.72rem }` beat the first version of this
       and the headings stayed at 11.5px. The rule is "nothing on a phone is smaller than 12.5px",
       which is exactly the kind of absolute limit !important exists for. */
    .small, .help, .muted, .tag, .status, .doclist__meta, .tile__desc,
    table.data, table.data th, table.data td, table.data thead th,
    .event__mon, .doclist__icon, .crumbs, .agrow__num, .field .help,
    .settings > summary .small, .addr label.small, .joinbar .small,
    .mins__assoc, .mins__meta dt, .mins__att h3, .mins__foot p, .mins__who {
        font-size: max(0.78rem, 12.5px) !important;
    }

    /* Real controls: tappable. Buttons, the menu, disclosure triangles, and select boxes. */
    .btn, .btn--sm, button, select, summary, .nav-toggle, .nav__toggle,
    input[type=submit], input[type=button] {
        min-height: 44px;
    }
    .btn, .btn--sm { padding-block: 11px; }
    summary { padding-block: var(--s2); }
    /* A checkbox stays checkbox-sized - blowing it up to 44px looks wrong. What has to be tappable
       is the LABEL beside it, so the whole row is the target. Matters most on the public forms: the
       "I agree to the terms" tick on /f/card-replacement was a 22px box on a phone. */
    input[type=checkbox], input[type=radio] { min-width: 22px; min-height: 22px; }
    label:has(> input[type=checkbox]), label:has(> input[type=radio]),
    .check, .check label, .checkrow, .checkrow label {
        display: flex; align-items: center; gap: var(--s2);
        min-height: 44px; cursor: pointer;
    }
    input[type=checkbox] + label, input[type=radio] + label {
        display: inline-flex; align-items: center; min-height: 44px; cursor: pointer;
    }

    /* Navigation links are navigation, not prose - give them room too. The footer's link lists were
       missed the first time round and stayed 16px tall. A link inside a sentence is left alone: it is
       text, and padding it out would break the line it sits in. */
    #primary-nav a, .nav a, .crumbs a,
    /* table.data is not always inside .tbl-wrap - the admin document lists are not, and their title
       links stayed 16px because of it. Target the table, not the wrapper. */
    .footer a, .footer ul li a, ul.small li a, .doclist a, table.data td a, .doclist__title a {
        display: inline-block; padding-block: 10px;
    }

    /* >>> A TELEPHONE NUMBER ON A PHONE IS THE THING PEOPLE TAP. <<< The contact card's number and
       email address were 22px and 16px tall - the two most tappable items on the site and the two
       smallest. Padded only when the link is ALONE in its parent, so the ones sitting inside a
       sentence ("email lmpoadirectors@gmail.com and they will tell you...") keep their line intact -
       see the note above about not padding a link inside prose. */
    p > a[href^="tel:"]:only-child, p > a[href^="mailto:"]:only-child,
    strong > a[href^="tel:"]:only-child, strong > a[href^="mailto:"]:only-child,
    li > a[href^="tel:"]:only-child, li > a[href^="mailto:"]:only-child {
        display: inline-block; padding-block: 11px; min-height: 44px;
    }

    /* Buttons in a row stack instead of squeezing to nothing. */
    .formbar, .savebar { gap: var(--s2); }
    .formbar .btn, .savebar .btn { flex: 1 1 auto; justify-content: center; }
}

/* A temporary password, shown once on the Owners screen. Big and monospaced so it can be read out
   over the telephone without a mistake, and selectable in one go. */
.issued {
    font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
    font-size: clamp(1.15rem, 4vw, 1.6rem); font-weight: 700; letter-spacing: .02em;
    color: var(--navy-800); background: #fff; border: 2px dashed var(--amber-500);
    border-radius: var(--radius-sm); padding: var(--s3) var(--s4); margin: var(--s3) 0;
    user-select: all; word-break: break-all;
}

/* ── Grouped lists: the divider is a divider, not a heading ────────────────────────────────────
   `.statusgroup` had NO CSS, so every group label rendered at full <h2> size. Travis 2026-09-01 on
   the inventory: *"the font is huge"*. It is a quiet rule with a count on the end, which is all a
   divider between groups of rows needs to be. */
.statusgroup {
    display: flex; align-items: baseline; gap: var(--s2);
    margin: var(--s5) 0 var(--s2); padding-bottom: 4px;
    border-bottom: 1px solid var(--line);
    font-size: .78rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
    color: var(--ink-500);
}
.statusgroup:first-of-type { margin-top: var(--s3); }
.statusgroup__n {
    font-size: .72rem; font-weight: 700; letter-spacing: 0;
    background: var(--navy-100); color: var(--navy-700);
    border-radius: 2em; padding: 1px 8px;
}
/* A single letter reads better as a mark than as a word. */
.statusgroup--letter {
    font-size: .95rem; letter-spacing: .02em; color: var(--navy-700);
}
/* Where a thing lives, beside its name on the list. */
.tag--place { background: var(--navy-100); color: var(--navy-700); }

/* ── "Waiting on the board" strip ──────────────────────────────────────────────────────────────
   Travis asked for it "just small", above the section boxes. Each pill is a link to the screen where
   the work is done, and the whole strip is absent when there is nothing waiting. Wraps on a phone. */
.waiting {
    display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s3);
    margin: 0 0 var(--s5); padding: var(--s3) var(--s4);
    border: 1px solid var(--line); border-left: 5px solid var(--amber-500);
    border-radius: var(--radius-sm); background: #fffaf3;
}
.waiting__lead {
    font-size: .72rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
    color: var(--ink-500);
}
.waiting__list { display: flex; flex-wrap: wrap; gap: var(--s2); list-style: none; margin: 0; padding: 0; }
/* >>> THESE HAVE TO SHOUT, OR THEY ARE WALLPAPER. <<<
   Travis 2026-09-01: *"can we make these be a color that makes it stand out now its the same color
   just blends in"*. They were navy-100 on a paper-tint strip - two near-whites, so a job waiting on
   the board read as decoration. Solid amber now, which is the same weight as the Admin button, and
   the ones that are genuinely overdue go solid red. */
.waiting__item {
    display: inline-block; font-size: .85rem; font-weight: 700; text-decoration: none;
    background: var(--amber-500); color: var(--navy-900);
    border-radius: 2em; padding: 6px 14px; border: 1px solid var(--amber-600);
    box-shadow: 0 1px 2px rgba(7,35,56,.12);
}
.waiting__item:hover, .waiting__item:focus-visible {
    background: var(--navy-900); color: #fff; border-color: var(--navy-900);
}
/* An open incident report, minutes sent back for changes, a document about to lapse. */
.waiting__item.is-warn {
    background: var(--danger); color: #fff; border-color: #7d1d22;
}
.waiting__item.is-warn:hover, .waiting__item.is-warn:focus-visible {
    background: #7d1d22; color: #fff;
}
@media (max-width: 720px) {
    .waiting { flex-direction: column; align-items: flex-start; }
    .waiting__item { padding: 9px 14px; }
}

/* The "You may edit" strip: same shape as the reminders, different colour so the two do not read as
   one list. Teal is "waiting on you"; amber-bordered green here is "you have permission". */
.waiting--edit { border-left-color: var(--amber-500); }
.waiting__item.is-edit { background: #eef4ea; color: #3c5c2a; }
.waiting__item.is-edit:hover, .waiting__item.is-edit:focus-visible { background: #4a7a33; color: #fff; }


/* ── Things that open and close ────────────────────────────────────────────────────────────────
   >>> WORDS, NOT A SYMBOL. <<<
   Travis 2026-09-01, in order: *"that little arrow is everywhere places collapse and no one will know
   what that tiny tiny arrow does needs to be bigger or maaybe better a different sysbol to show it
   expands"*, then on the plus-in-a-circle that replaced it: *"not impressed with the circle + to show
   collapsed. when i see a + sign i think add not expand so maybe just a small Expand once expanded
   goes to Collapse? or Show more / Show less"*.

   He is right - a plus means add. So it says **Show more**, and **Show less** once open. No glyph to
   interpret, and it looks like a control because it is styled as one: a small bordered pill, right
   aligned like the "read more" it is, with the whole row highlighting on hover.

   Applied by SELECTOR (`details:not(.nav__more)`) rather than a class list, because a class list had
   already missed two collapsibles and cannot cover ones added later. .nav__more is the header's
   overflow menu and keeps its own chevron. */
details:not(.nav__more) > summary {
    display: flex; align-items: center; gap: var(--s3);
    list-style: none; cursor: pointer;
    border-radius: var(--radius-sm);
    transition: background .12s ease;
}
details:not(.nav__more):not(.pick__more) > summary::-webkit-details-marker { display: none; }

details:not(.nav__more):not(.pick__more) > summary::after {
    content: "Show more";
    order: 99;                     /* last, whatever else is in the row */
    margin-left: auto;             /* pushed to the right-hand end, like a "read more" */
    flex: 0 0 auto;
    font-size: .8rem; font-weight: 700; line-height: 1;
    color: var(--navy-700); background: var(--paper);
    border: 1px solid var(--navy-500); border-radius: 2em;
    padding: 7px 14px; white-space: nowrap;
}
details:not(.nav__more):not(.pick__more)[open] > summary::after { content: "Show less"; }

details:not(.nav__more):not(.pick__more) > summary:hover { background: var(--paper-tint); }
details:not(.nav__more):not(.pick__more) > summary:hover::after {
    background: var(--navy-700); color: #fff; border-color: var(--navy-700);
}
details:not(.nav__more) > summary:focus-visible { outline: 2px solid var(--navy-500); outline-offset: 2px; }

/* The heading inside a summary was `display:inline` so the old glyph could trail it. It is a flex
   child now, and the note beside it wraps underneath on a narrow screen instead of squeezing. */
.settings > summary h2 { display: block; margin: 0; font-size: 1.05rem; }
.settings > summary { padding: var(--s2) var(--s2) var(--s2) 0; flex-wrap: wrap; }
/* Order matters in a wrapping flex row: the note was order 50 and the button 99, so the note took the
   whole second line and pushed "Show more" onto a third, adrift from the heading. The button sits with
   the heading on line one; the note wraps underneath it. */
.settings > summary .small { flex: 1 1 100%; order: 100; }
.itemrow > summary { padding: 6px var(--s2) 6px 0; }

@media (max-width: 720px) {
    /* Letting the label drop onto its own line pushed one inventory row to 159px on a phone - 17 of
       those is most of a screen each. It stays on the title's line, pinned right; the description
       wraps underneath it instead. */
    details:not(.nav__more) > summary { flex-wrap: wrap; align-items: flex-start; }
    details:not(.nav__more) > summary::after { margin-left: auto; padding: 8px 14px; order: 2; }
    .topic > summary .topic__title { order: 1; flex: 1 1 auto; min-width: 0; }
    .topic > summary .topic__meta { order: 3; flex: 1 1 100%; margin-top: 2px; }
}


/* "Saved." after an import that deletes things. It sits at the very top and has to be the first thing
   read - Travis committed a real import and asked "did it do something", because the confirmation was
   two small notices halfway down several screens of numbers. */
.saved { border-left: 6px solid #2f7a3d; }
.saved__head { margin: 0 0 var(--s2); font-size: 1.05rem; }
.saved__list { margin: 0 0 var(--s3); padding-left: var(--s5); }
.saved__list li + li { margin-top: 4px; }


/* An owner's lots, each with its street address where it has one. Travis: "if they have lot number and
   phyiscal address for the lot list both some will just have lot #". The number is the anchor, so it is
   fixed-width and bold; the address trails it in grey. */
.lotlist { list-style: none; margin: 0; padding: 0; }
.lotlist li { display: flex; gap: var(--s2); align-items: baseline; }
.lotlist li + li { margin-top: 2px; }
.lotlist__no {
    flex: 0 0 auto; min-width: 3.6em; font-weight: 700; color: var(--navy-700);
    font-variant-numeric: tabular-nums;
}
.lotlist__addr { color: var(--ink-500); }
@media (max-width: 720px) {
    .lotlist li { flex-wrap: wrap; }
    .lotlist__addr { flex: 1 1 100%; margin-left: 3.6em; }
}

/* A sortable column heading. It has to look like something you can click - the whole cell is the
   target, and the arrow shows only on the column actually in use so there is nothing to decode. */
th > a.sortcol {
    display: block; margin: calc(var(--s3) * -1) calc(var(--s3) * -1); padding: var(--s3);
    color: inherit; text-decoration: none; white-space: nowrap;
}
th > a.sortcol:hover, th > a.sortcol:focus-visible {
    background: var(--navy-100); color: var(--navy-800); text-decoration: underline;
}
th[aria-sort]:not([aria-sort="none"]) { background: var(--navy-100); color: var(--navy-800); }


/* ══════════════════════════════════════════════════════════════════════════════════════════════
   SECTION TABS.

   Travis 2026-09-01: *"i hate the way this settings page works"*, *"its just a long list of stuff
   terrible to navigate"*. The settings page was 8,008px of one form. These are plain links - no
   JavaScript, and they wrap onto as many lines as a phone needs rather than scrolling sideways.
   ══════════════════════════════════════════════════════════════════════════════════════════════ */
.tabrow { display: flex; flex-wrap: wrap; gap: 6px; margin-block: var(--s4);
          border-bottom: 2px solid var(--line); padding-bottom: 8px; }
.tab { display: inline-flex; align-items: center; gap: 6px; padding: 8px 13px;
       border: 1px solid var(--line); border-radius: 999px; background: var(--paper);
       color: var(--navy-700); text-decoration: none; font-size: .9rem; font-weight: 600;
       line-height: 1.2; min-height: 40px; }
.tab:hover { background: var(--paper-tint); border-color: var(--navy-500); color: var(--navy-800); }
.tab.is-on { background: var(--navy-700); border-color: var(--navy-700); color: #fff; }
.tab.is-on:hover { background: var(--navy-800); color: #fff; }
.tab__n { font-size: .75rem; font-weight: 600; opacity: .7; }
/* A tab that leaves this page for another one, so it does not pretend to be a peer of the rest. */
.tab--away { border-style: dashed; color: var(--teal-600); }
.tab--away:hover { color: var(--navy-800); }
@media (max-width: 560px) {
    .tab { flex: 1 1 auto; justify-content: center; }
}

/* A candidate row you tick. The whole card is the label, so the tap target is the card and not a 20px
   circle - most owners are on a phone. */
.candidate--pick { display: flex; gap: 12px; align-items: flex-start; padding: 14px 16px;
                   cursor: pointer; }
.candidate--pick:hover { background: var(--paper-tint); border-color: var(--navy-500); }
.candidate--pick input[type=checkbox] { margin-top: 3px; width: 20px; height: 20px; flex: 0 0 auto; }
.candidate--pick:has(input:checked) { border-color: var(--ok); background: #f1f9f4; }


/* ══════════════════════════════════════════════════════════════════════════════════════════════
   A NUMBERED PROCESS WITH ONE STEP LIT UP.

   Travis 2026-09-01: *"ok i added my stuff now where is the process i asked for"*. Three states
   and they have to be tellable apart at a glance without reading: done is quiet and ticked, NOW is
   the only one with colour, later is greyed. Colour on everything would say nothing.
   ══════════════════════════════════════════════════════════════════════════════════════════════ */
.steps { list-style: none; margin: var(--s4) 0 var(--s6); padding: 0;
         border: 1px solid var(--line); border-radius: 10px; background: #fff; overflow: hidden; }
.step { display: flex; gap: 12px; align-items: flex-start; padding: 12px 16px;
        border-top: 1px solid var(--line); }
.step:first-child { border-top: 0; }
.step__n { flex: 0 0 26px; height: 26px; border-radius: 999px; display: grid; place-items: center;
           font-size: .8rem; font-weight: 700; background: var(--paper-tint); color: var(--navy-700);
           border: 1px solid var(--line); }
.step__body { display: flex; flex-wrap: wrap; gap: 4px 12px; align-items: baseline; flex: 1 1 auto; }
.step__body > strong { flex: 0 0 auto; }
.step__what { color: var(--ink-soft, #5a6b78); font-size: .88rem; flex: 1 1 240px; }
.step form, .step .btn { flex: 0 0 auto; }

/* done - behind you, quiet, and the number becomes a tick. */
.step--done { background: #fbfdfc; }
.step--done .step__n { background: var(--ok); border-color: var(--ok); color: #fff; font-size: 0; }
.step--done .step__n::after { content: "\2713"; font-size: .85rem; }

/* now - the only coloured row on the strip. */
.step--now { background: #fffaf0; box-shadow: inset 4px 0 0 var(--amber-500); padding-left: 20px; }
.step--now .step__n { background: var(--amber-500); border-color: var(--amber-500);
                      color: var(--navy-900); }
.step--now > .step__body > strong { color: var(--navy-900); }

/* later - present so the shape of the whole process is visible, but plainly not yet. */
.step--later { color: var(--ink-soft, #5a6b78); }
.step--later .step__n { opacity: .55; }

@media (max-width: 560px) {
    .step__body { gap: 6px; }
    .step__what { flex: 1 1 100%; }
}


/* Long unbroken text - a pasted URL, or somebody testing with "blahblahblah" - has nowhere to wrap
   and rides out of its container. These are the places a person's own words are echoed back. */
/* >>> NOT td AND th. <<< Including them let the browser shrink a column below the width of its own
   words, so the roster table on a phone came out as vertical letters - "BOA RD ME MBE R". A table
   that does not fit belongs in a .tbl-wrap and scrolls sideways; it does not get its words broken.
   Caught in the screenshot of the very fix that caused it. */
.candidate span, .candidate__statement, .topic__title, .votelist li, .prose p, .prose li,
.step__what, .waiting__item { overflow-wrap: anywhere; }


/* ══════════════════════════════════════════════════════════════════════════════════════════════
   .tbl-wrap - THE CLASS EXISTED IN THE MARKUP AND HAD NO CSS AT ALL.

   Dozens of tables are wrapped in it, expecting it to scroll them. It never did, so a table too
   wide for a phone squeezed its columns instead - which is why the roster came out as vertical
   letters the moment words were allowed to break. A wide table should move sideways INSIDE its own
   box, never make the page itself scroll.

   overflow-y: hidden is paired on purpose - see the memory note
   feedback_overflow_x_creates_a_second_scroller: overflow-x alone makes a second vertical scroller.
   ══════════════════════════════════════════════════════════════════════════════════════════════ */
.tbl-wrap { overflow-x: auto; overflow-y: hidden; max-width: 100%; }
.tbl-wrap > table { min-width: max-content; }

/* ══════════════════════════════════════════════════════════════════════════════════════════════
   .data--wrap - A TABLE WHOSE FIRST COLUMN IS A SENTENCE.

   Travis 2026-09-03, on the to-do list: *"to do list has a scroll left to right for what to do should
   we just word wrap it to get rid of the left to right scroll"*. He is right, and min-width: max-content
   above is why: it makes the table as wide as its widest cell, so one long job pushed the whole thing
   sideways.

   >>> NOT A CHANGE TO .tbl-wrap. <<< Dozens of tables rely on that rule, and the roster is the reason it
   exists - see the note above about "BOA RD ME MBE R". So this is opt-in, and only the sentence column
   is allowed to wrap: the short columns keep white-space: nowrap so they can never be squeezed into
   vertical letters, and the sentence column absorbs whatever width is left.
   ══════════════════════════════════════════════════════════════════════════════════════════════ */
/* The submission somebody was pointed straight at. Landing on a page of identical folds with one
   quietly open is not obvious enough - it gets a mark, so the answer to "where am I" is instant.
   `.topic` already carries scroll-margin-top for the sticky masthead, so it clears the header. */
.topic--linked { outline: 2px solid var(--navy-600); outline-offset: 2px; }

.tbl-wrap > table.data--wrap { min-width: 0; width: 100%; table-layout: auto; }
table.data--wrap th, table.data--wrap td { white-space: nowrap; }
table.data--wrap .col--what { white-space: normal; overflow-wrap: anywhere; width: 100%; }
table.data--wrap td { vertical-align: top; }

/* >>> ON A PHONE IT STOPS BEING A TABLE. <<<
   Measured at 390px: letting the short columns wrap too left the sentence column 38px wide and 1,881px
   tall - vertical letters, exactly what the note above .tbl-wrap warns about - and still 33px of
   sideways scroll. Five columns do not fit in 390px and wrapping cannot make them.

   So each row becomes a block: the job, then its details with their column name in front, then the
   buttons. The header row is hidden because each value carries its own label. */
@media (max-width: 720px) {
    table.data--wrap, table.data--wrap tbody, table.data--wrap tr, table.data--wrap td {
        display: block; width: auto;
    }
    table.data--wrap thead { display: none; }
    table.data--wrap tr {
        padding: var(--s3) 0; border-bottom: 1px solid var(--line);
    }
    table.data--wrap tr:last-child { border-bottom: 0; }
    table.data--wrap td {
        border: 0; padding: 2px 0; white-space: normal; overflow-wrap: anywhere;
    }
    table.data--wrap .col--what { font-weight: 600; padding-bottom: var(--s2); }
    /* The column name in front of its value, so a bare "unassigned" still means something. */
    table.data--wrap td[data-label]:not(.col--what)::before {
        content: attr(data-label) ": "; color: var(--ink-600); font-weight: 600;
    }
    table.data--wrap td:empty { display: none; }
}


/* ══════════════════════════════════════════════════════════════════════════════════════════════
   THE BALLOT ROW - built for a thumb.

   Travis 2026-09-02: *"most are going to vote on there phone so it needs to be phone usable"*.
   The first version put a 22px tick box above the name with the whole biography inline: about
   2,000px of scrolling for three candidates, and no way to see what you had ticked.

   Now: name and box on one 56px row, biography behind a toggle. A ticked row is obvious at a
   glance - green edge, tinted, and the name goes bold - because on a phone you cannot see the
   whole ballot at once and have to trust what you already did.
   ══════════════════════════════════════════════════════════════════════════════════════════════ */
.pick { border: 1px solid var(--line); border-radius: 10px; background: #fff;
        margin: 0 0 8px; overflow: hidden; }
.pick__row { display: flex; align-items: center; gap: 12px; padding: 14px 16px;
             cursor: pointer; min-height: 56px; }
.pick__row:hover { background: var(--paper-tint); }
/* 26px, and it must not shrink - a tick box you can miss with a thumb is the whole problem. */
.pick__row input { width: 26px; height: 26px; flex: 0 0 26px; margin: 0; accent-color: var(--ok); }
.pick__name { font-weight: 650; line-height: 1.3; overflow-wrap: anywhere; }

/* The selected state, on the ROW - :has means no JavaScript is needed for it. */
.pick:has(input:checked) { border-color: var(--ok); background: #f1f9f4;
                           box-shadow: inset 4px 0 0 var(--ok); }
.pick:has(input:checked) .pick__name { color: #14543a; }

/* "Read about them" - quiet, and full width so it is easy to hit. */
.pick__more { border-top: 1px solid var(--line); }
.pick__more > summary { padding: 12px 16px; cursor: pointer; font-size: .88rem;
                        color: var(--teal-600); font-weight: 600; min-height: 44px;
                        display: flex; align-items: center; }
.pick__more > summary::-webkit-details-marker { display: none; }
.pick__more[open] > summary { border-bottom: 1px solid var(--line); }
.pick__more > p { padding: 12px 16px; margin: 0; font-size: .9rem; }

.pick__more > summary::marker, .pick__more > summary::-webkit-details-marker { display: none; content: ""; }

/* Folding status groups on the boat registrations page. The header still shows the count when the
   group is shut, so the page reads as a summary rather than a wall of rows. */
details.statusfold > summary { display:flex; align-items:center; gap:.6rem; cursor:pointer; }
details.statusfold > summary h3 { margin:0; }
details.statusfold > summary .statusgroup__n { margin-left:0; }

/* ── Tinted pages, tiles that read as separate things ────────────────────────────────── */
/* Travis 2026-11-13: "the site other then the main page is very just white no color ... hard to tell
   where the boxes separate". Every page sits on a light blue-grey, so white cards, tables and inputs
   stand out from it; every tile gets a teal edge, a shadow and an icon. */
:root { --page-bg: #eef3f6; }
body { background: var(--page-bg); }
.section--tint { background: #e3ebf1; border-block-color: #d6e0e8; }
table.data { background: var(--paper); }
/* A document list is a white panel of rows, not loose text on the tinted page. */
.doclist {
    background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: var(--shadow-sm); padding: 0 var(--s3);
}
.doccard { box-shadow: var(--shadow-sm); }
/* "Nothing here yet" sat left of centre: p has a max-width, so it needs centring inside the box. */
.empty p { margin-inline: auto; }

.tile { border-left: 5px solid var(--teal-500); box-shadow: var(--shadow-sm); }
.tile:hover { border-left-color: var(--amber-500); }
.tile__icon svg {
    width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8;
    stroke-linecap: round; stroke-linejoin: round;
}
.tile .tile__icon { color: var(--navy-500); }

/* Icon on the left, words on the right. Every tile in a grid is the same height. */
.card.tile--icon, .tile--form { flex-direction: row; align-items: flex-start; gap: var(--s3); }
.tile__body { display: block; flex: 1; min-width: 0; }
/* Compact, like the Forms page. Travis 2026-11-13 on the home page boxes: "can [they] be a bit smaller
   there pretty big". The description stops at two lines; the full wording is on the page it opens. */
.card.tile--icon { align-items: center; padding: 14px 16px 14px 14px; }
.grid:has(> .tile--icon) { gap: var(--s3); }
.card.tile--icon h3 { margin: 0 0 2px; font-size: 1.02rem; }
.card.tile--icon p {
    margin: 0; font-size: .88rem; line-height: 1.4; color: var(--ink-700);
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.card.tile--icon p.tile__count { margin-top: 4px; display: block; font-size: .76rem; color: var(--ink-500); }
/* Only side by side: in one column on a phone, equal heights just pad every card to the tallest. */
@media (min-width: 700px) {
    .grid:has(> .tile--icon), .grid:has(> .tile-cell > .tile--icon), .form-tiles { grid-auto-rows: 1fr; }
}

/* The Forms page: tighter tiles, the description cut at two lines so one long intro cannot stretch
   every row. */
.form-tiles { gap: var(--s3); }
@media (min-width: 700px) { .form-tiles { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 940px) { .form-tiles { grid-template-columns: repeat(3, 1fr); } }
.tile--form { align-items: center; padding: 12px 14px 12px 12px; }
.tile--form:hover { transform: translateY(-1px); }
.tile--form h3 { margin: 0 0 2px; font-size: 1.02rem; color: var(--navy-900); }
.tile--form .tag { font-size: .72rem; }
.tile--form .small { margin: 0 0 2px !important; }
.tile__summary {
    margin: 0; font-size: .88rem; line-height: 1.35; color: var(--ink-700);
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* Icon picker in the form editor */
.icon-pick { border: 0; padding: 0; margin: 0 0 var(--s5); display: flex; flex-wrap: wrap; gap: 6px; }
.icon-pick .help { flex-basis: 100%; margin: 4px 0 0; }
.icon-pick legend { font-weight: 600; margin-bottom: var(--s2); }
.icon-pick label.icon-pick__opt {
    display: inline-flex; font-weight: 400; min-height: 0; position: relative; flex-direction: column; align-items: center; gap: 4px; width: 92px;
    padding: 8px 4px; margin: 0; border: 2px solid var(--line); border-radius: var(--radius-sm);
    cursor: pointer; text-align: center; vertical-align: top; background: var(--paper);
}
.icon-pick__opt input { position: absolute; opacity: 0; pointer-events: none; }
.icon-pick__opt:has(input:checked) { border-color: var(--teal-500); background: #f2f9fb; }
.icon-pick__opt:has(input:focus-visible) { outline: 2px solid var(--navy-500); outline-offset: 2px; }
.icon-pick__name { font-size: .72rem; line-height: 1.2; color: var(--ink-700); }

/* ── Site search ────────────────────────────────────────────────────────────────────────── */
.visually-hidden {
    position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.sitesearch { display: flex; gap: var(--s2); max-width: 640px; margin: var(--s4) 0 var(--s5); }
.sitesearch input { flex: 1; min-width: 0; }
.sitesearch .btn { flex: none; }
.results { list-style: none; margin: var(--s3) 0 0; padding: 0; display: grid; gap: var(--s3); }
.result__link {
    display: flex; gap: var(--s3); align-items: flex-start; text-decoration: none; color: inherit;
    background: var(--paper); border: 1px solid var(--line); border-left: 5px solid var(--teal-500);
    border-radius: var(--radius); padding: 12px 14px 12px 12px; box-shadow: var(--shadow-sm);
}
.result__link:hover { border-left-color: var(--amber-500); box-shadow: var(--shadow-md); }
.result__link .tile__icon { color: var(--navy-500); }
.result__title { display: block; font-weight: 650; color: var(--navy-900); line-height: 1.3; }
.result__kind { display: block; font-size: .74rem; text-transform: uppercase; letter-spacing: .06em; color: var(--teal-600); margin-top: 2px; }
.result__snip { display: block; font-size: .88rem; line-height: 1.45; color: var(--ink-700); margin-top: 4px; }
.result__snip mark { background: #fdf1e2; color: inherit; padding: 0 1px; border-radius: 2px; }
.hero .sitesearch { margin: var(--s5) 0 0; }
.hero .sitesearch input { background: #fff; border-color: transparent; }
.hero .sitesearch .btn--primary { background: var(--teal-500); border-color: var(--teal-500); }
.nav__search { display: inline-flex; align-items: center; gap: 5px; }
/* Icon only in the full-width header - the word pushed "Owner sign in" onto a second line at 1280px.
   In the collapsed phone menu there is room, so the word comes back there. */
@media (min-width: 1151px) { .nav__search span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); } }
.nav__search svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
