:root {
    --ink: #17454c;
    --teal: #1f737e;
    --teal-deep: #1a616b;
    --teal-soft: #e4f1f3;
    --orange: #b8560a;
    --orange-deep: #9c4807;
    --orange-soft: #fbe8d6;
    --gold: #f0a93b;
    --green: #4e9e55;
    --green-soft: #e7f3e8;
    --green-deep: #2f6b35;
    --cream: #fbf7ef;
    --card: #ffffff;
    --muted: #556669;
    --line: #e7e0d2;
    --danger: #b3402a;
    --radius: 16px;
    --shadow: 0 1px 2px rgba(23, 69, 76, .06), 0 4px 16px rgba(23, 69, 76, .07);
    --font: "Nunito", ui-rounded, "Segoe UI", system-ui, -apple-system, sans-serif;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
html { height: 100%; }

body {
    margin: 0;
    font-family: var(--font);
    font-size: 16px;
    line-height: 1.45;
    color: var(--ink);
    background: var(--cream);
    display: flex;
    flex-direction: column;
    min-height: 100dvh;
}

.app-header {
    position: sticky;
    top: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 16px;
    padding-top: calc(10px + env(safe-area-inset-top));
    background: rgba(251, 247, 239, .92);
    backdrop-filter: blur(8px);
    border-bottom: 1px solid var(--line);
}

.brand-mark, .avatar, .empty-owl {
    display: inline-block;
    flex: none;
    border-radius: 50%;
    background: url("/static/icons/mark-fallback.png") no-repeat;
    background-size: 165%;
    background-position: 50% 22%;
}
.brand-mark { width: 40px; height: 40px; border: 2px solid var(--teal-soft); }
/* #1386: brand-text must shrink (not wrap) once the now-nowrap .app-nav
   claims more row width — otherwise the tagline wraps to two lines instead
   and the header-height regression just moves from the nav to here. */
.brand-text { min-width: 0; overflow: hidden; }
.wordmark { font-weight: 800; font-size: 1.2rem; letter-spacing: -.01em; color: var(--teal-deep); line-height: 1.1; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wordmark span { color: var(--orange); }
.tagline { font-size: .75rem; font-weight: 600; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.profile-btn { margin-left: auto; }

/* #1386: nav buttons must stay single-line at narrow widths (was wrapping
   "What's on" to two lines, growing the header 61->76px). */
.app-nav { display: flex; gap: 4px; align-items: center; flex-wrap: nowrap; }
.app-nav button { white-space: nowrap; min-height: 44px; }
/* T2355 / UX-11: the active tab was indistinguishable from the other three. */
.app-nav button[aria-current='page'] { background: var(--teal-soft); color: var(--teal-deep); }

.app-main { flex: 1; width: 100%; max-width: 520px; margin: 0 auto; padding: 16px 16px 96px; }
.panel[hidden] { display: none; }

.bubble-row { display: flex; align-items: flex-end; gap: 8px; margin: 10px 0; animation: rise .28s ease-out both; }
.avatar { width: 30px; height: 30px; }
.bubble { background: var(--teal-soft); color: var(--ink); border-radius: var(--radius); border-bottom-left-radius: 4px; padding: 10px 14px; max-width: 85%; font-size: .95rem; }
.bubble p { margin: 0; }
.bubble p + p { margin-top: 6px; }

.typing { display: inline-flex; gap: 5px; padding: 4px 2px; }
.typing i { width: 7px; height: 7px; border-radius: 50%; background: var(--teal); opacity: .35; animation: blink 1.2s infinite; }
.typing i:nth-child(2) { animation-delay: .2s; }
.typing i:nth-child(3) { animation-delay: .4s; }
@keyframes blink { 0%, 80%, 100% { opacity: .35; } 40% { opacity: 1; } }

.block-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 14px 0; }
.block-grid button { position: relative; font: inherit; font-weight: 700; color: var(--ink); min-height: 56px; padding: 8px 12px; background: var(--card); border: 1.5px solid var(--line); border-radius: var(--radius); cursor: pointer; display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 1px; transition: border-color .15s, background .15s, transform .1s; }
.block-grid button small { font-weight: 600; font-size: .74rem; color: var(--muted); }
.block-weather { position: absolute; bottom: 8px; right: 12px; font-size: .85rem; opacity: .85; }
.block-grid button:active { transform: scale(.97); }
.block-grid button.selected { background: var(--teal-soft); border-color: var(--teal); position: relative; }
.block-grid button.selected::after { content: "\2713"; position: absolute; top: 8px; right: 12px; color: var(--teal); font-weight: 800; }

.btn-primary, .btn-secondary, .btn-ghost, .btn-teal { font: inherit; font-weight: 700; border-radius: 999px; cursor: pointer; transition: background .15s, transform .1s, opacity .15s; }
.btn-primary:active, .btn-secondary:active, .btn-teal:active { transform: scale(.98); }
.btn-primary { display: block; width: 100%; padding: 14px 20px; background: var(--orange); color: #fff; border: none; font-size: 1rem; }
.btn-primary:hover { background: var(--orange-deep); }
.btn-primary:disabled { opacity: .6; cursor: default; }
.btn-secondary { padding: 10px 18px; background: transparent; color: var(--teal-deep); border: 1.5px solid var(--teal); }
.btn-secondary:hover { background: var(--teal-soft); }
.btn-ghost { padding: 10px 12px; background: transparent; color: var(--teal); border: none; text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
.btn-ghost.small { font-size: .85rem; padding: 6px 4px; }
/* #1397: filled teal — the "leaves the app to transact" weight (D2, DESIGN.md 2026-08-20). */
.btn-teal { padding: 10px 18px; background: var(--teal); color: #fff; border: 1.5px solid var(--teal); font-size: .9rem; text-decoration: none; display: inline-flex; align-items: center; justify-content: center; min-height: 44px; }
.btn-teal:hover { background: var(--teal-deep); border-color: var(--teal-deep); }

#cards-container { margin-top: 4px; }
.events-header { display: flex; align-items: center; justify-content: space-between; margin: 0 0 12px; }
.events-header h2 { margin: 0; font-size: 1.2rem; font-weight: 800; }
.events-group { margin: 0 0 20px; }
.events-group h3 { margin: 0 0 10px; font-size: .95rem; font-weight: 800; color: var(--teal-deep); }
.card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); margin: 0 0 16px; overflow: hidden; }
.card-photo { position: relative; height: 150px; display: flex; align-items: center; justify-content: center; font-size: 3rem; background: var(--teal-soft); }
.card-photo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.activity-type-badge { position: absolute; top: 10px; left: 10px; background: rgba(251, 247, 239, .95); color: var(--teal-deep); font-size: .8rem; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; padding: 4px 10px; border-radius: 999px; }
.closes-badge { position: absolute; top: 10px; right: 10px; background: var(--gold); color: #3a2a06; font-size: .8rem; font-weight: 800; padding: 4px 10px; border-radius: 999px; }
.card-body { padding: 14px 16px 16px; }
.card-body h3 { margin: 0 0 2px; font-size: 1.1rem; font-weight: 800; letter-spacing: -.01em; }
.card-reason { margin: 2px 0 6px; font-size: .88rem; font-style: italic; color: var(--teal-deep); }
.card-reason::before { content: "\2726 "; font-style: normal; color: var(--gold); }
.card-desc { margin: 0 0 10px; font-size: .92rem; color: var(--muted); }
.chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 14px; }
.chip { background: var(--teal-soft); color: var(--teal-deep); font-size: .78rem; font-weight: 700; padding: 4px 11px; border-radius: 999px; white-space: nowrap; }
.chip-sponsored { background: var(--orange-soft); color: var(--orange-deep); }
.chip-session { background: var(--green-soft); color: var(--green-deep); }
.actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.actions .btn-primary { display: inline-block; width: auto; flex: 1 1 auto; padding: 11px 16px; font-size: .92rem; }
.actions .btn-secondary { padding: 10px 14px; font-size: .9rem; }
.actions .btn-ghost { font-size: .9rem; }
.actions .btn-teal { padding: 10px 14px; font-size: .9rem; }
/* T2356 / UX-13: "Report a problem" is demoted out of .actions (D2 restored:
   exactly four ranked actions) into a quiet footer below them. It is a
   tertiary, once-in-a-while control -- a ghost link separated by a hairline,
   not a peer of Lock it in. Also UX-8: the picker now replaces THIS row, so a
   mis-tap can no longer destroy the card's primary CTA. */
.card-footer { margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--line); }
.card-footer:empty { display: none; }
.card-footer .report-problem-btn { padding: 8px 0; font-size: .8rem; font-weight: 700; color: var(--muted); text-decoration-thickness: 1px; }
.card-footer .report-problem-btn:hover, .card-footer .report-problem-btn:focus-visible { color: var(--teal-deep); }
.card-footer .reason-picker { margin-top: 2px; }
.card-footer .report-cancel-chip { color: var(--muted); }
.card-reported { margin: 0; padding: 8px 0; font-size: .8rem; font-weight: 700; color: var(--green); }

.book-link { display: inline-flex; align-items: center; min-height: 44px; margin-top: 4px; font-size: .88rem; font-weight: 700; color: var(--orange); text-decoration: underline; text-underline-offset: 3px; }
.more-reply { margin: 12px 0 0; padding: 10px 12px; background: var(--teal-soft); border-radius: 12px; font-size: .9rem; animation: rise .25s ease-out both; }

.reason-picker { width: 100%; animation: rise .22s ease-out both; }
.reason-picker .picker-label { display: block; font-size: .85rem; font-weight: 700; color: var(--muted); margin-bottom: 8px; }
.reason-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.reason-chip { font: inherit; font-size: .86rem; font-weight: 700; color: var(--ink); background: var(--cream); border: 1.5px solid var(--line); border-radius: 999px; padding: 9px 14px; cursor: pointer; transition: border-color .15s, background .15s; }
.reason-chip:hover, .reason-chip:focus-visible { border-color: var(--teal); background: var(--teal-soft); }
.other-row { display: flex; gap: 8px; width: 100%; }
.other-row textarea { flex: 1; font: inherit; font-size: .9rem; border: 1.5px solid var(--line); border-radius: 12px; padding: 9px 12px; resize: none; }
.other-row textarea:focus { outline: 2px solid var(--teal); outline-offset: 0; border-color: transparent; }

.locked-band { background: var(--green-soft); border-top: 1px solid #d3e8d4; padding: 12px 16px; display: flex; align-items: center; justify-content: space-between; gap: 10px; animation: rise .25s ease-out both; }
.locked-band .locked-text { font-weight: 800; color: var(--green); font-size: .95rem; }
.locked-band .locked-sub { display: block; font-weight: 600; font-size: .8rem; color: var(--muted); }
.locked-band a { flex: none; font-size: .85rem; font-weight: 700; color: var(--teal-deep); text-decoration: underline; text-underline-offset: 3px; }
.card.locked { border-color: #cbe3cc; }
.card-error { margin: 8px 0 0; font-size: .82rem; color: var(--danger); }

.card-removing { opacity: 0; transform: translateX(24px); transition: opacity .2s ease-out, transform .2s ease-out; }
@keyframes slideIn { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: translateY(0); } }
.card-slide-in { animation: slideIn .28s ease-out both; }
@keyframes rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }

.skeleton-card { border-radius: var(--radius); border: 1px solid var(--line); overflow: hidden; margin-bottom: 16px; background: var(--card); }
.skeleton-card .sk-photo { height: 150px; }
.skeleton-card .sk-line { height: 14px; border-radius: 7px; margin: 12px 16px; }
.skeleton-card .sk-line.short { width: 55%; }
.sk-photo, .sk-line { background: linear-gradient(100deg, #eef2ee 40%, #f7f4ec 50%, #eef2ee 60%); background-size: 200% 100%; animation: shimmer 1.3s infinite linear; }
@keyframes shimmer { to { background-position: -200% 0; } }

.empty-state { text-align: center; padding: 36px 24px; animation: rise .25s ease-out both; }
.empty-state[hidden] { display: none; }
.empty-owl { width: 84px; height: 84px; opacity: .9; margin-bottom: 8px; }
.empty-state h2 { margin: 0 0 6px; font-size: 1.15rem; font-weight: 800; }
.empty-state p { margin: 0 auto 18px; max-width: 300px; color: var(--muted); font-size: .92rem; }

/* T2356 / UX-19: #followup-panel had NO rules anywhere -- the one screen the
   app used to push at users unprompted rendered as a raw browser form (two
   bare <select>s and a 48x21px Arial button). It now reuses the app's own
   card + reason-chip vocabulary, so it looks like the product it is part of.
   UX-10: the header carries the exit this panel never had. */
.followup-header { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 0 0 6px; }
.followup-header h2 { margin: 0; font-size: 1.2rem; font-weight: 800; }
.followup-intro { margin: 0 0 14px; color: var(--muted); font-size: .9rem; }
.followup-item { padding: 14px 16px 16px; margin-bottom: 14px; }
.followup-item h3 { margin: 0 0 2px; font-size: 1.05rem; font-weight: 800; letter-spacing: -.01em; }
.followup-slot { margin: 0 0 12px; font-size: .88rem; color: var(--muted); }
.followup-question + .followup-question { margin-top: 12px; }
.followup-question .picker-label { display: block; font-size: .85rem; font-weight: 700; color: var(--muted); margin-bottom: 8px; }
.followup-item .reason-chip.selected { border-color: var(--teal); background: var(--teal-soft); color: var(--teal-deep); }
.followup-item .feedback .btn-primary { width: 100%; margin-top: 14px; }
.followup-item.followup-done { opacity: .6; }

/* UX-10: the Sunday follow-up is OFFERED from inside the Plan page instead of
   replacing it. Quiet enough not to outrank the weekend the user came to plan. */
.followup-prompt[hidden] { display: none; }
.followup-prompt-card { padding: 12px 14px; margin-bottom: 12px; }
.followup-prompt-text { margin: 0 0 10px; font-size: .92rem; font-weight: 700; color: var(--teal-deep); }
.followup-prompt-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }

.events-loading-state { padding: 24px; text-align: center; color: var(--muted); font-size: .92rem; }
.events-loading-state[hidden] { display: none; }

.composer { position: fixed; left: 0; right: 0; bottom: 0; z-index: 20; display: flex; align-items: flex-end; gap: 8px; max-width: 520px; margin: 0 auto; padding: 10px 12px; padding-bottom: calc(10px + env(safe-area-inset-bottom)); background: rgba(251, 247, 239, .95); backdrop-filter: blur(8px); border-top: 1px solid var(--line); }
.composer[hidden] { display: none; }
.composer textarea { flex: 1; font: inherit; font-size: .95rem; color: var(--ink); background: var(--card); border: 1.5px solid var(--line); border-radius: 22px; padding: 11px 16px; resize: none; max-height: 108px; }
.composer textarea:focus { outline: 2px solid var(--teal); outline-offset: 0; border-color: transparent; }
.composer textarea::placeholder { color: #9aa8aa; }
.send-btn { flex: none; width: 44px; height: 44px; border-radius: 50%; border: none; background: var(--teal); color: #fff; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background .15s, transform .1s; }
.send-btn:hover { background: var(--teal-deep); }
.send-btn:active { transform: scale(.94); }
.send-btn:disabled { opacity: .55; cursor: default; }
.send-btn svg { margin: 1px 2px 0 0; }

.auth-hero { text-align: center; padding: 20px 8px 4px; animation: rise .3s ease-out both; }
.auth-logo { width: 108px; height: 108px; border-radius: 50%; object-fit: cover; object-position: 50% 38%; border: 3px solid var(--teal-soft); box-shadow: var(--shadow); }
.auth-hero h1 { margin: 14px 0 6px; font-size: 1.5rem; font-weight: 800; letter-spacing: -.02em; line-height: 1.2; color: var(--teal-deep); }
.auth-hero p { margin: 0 auto; max-width: 320px; font-size: .93rem; color: var(--muted); }
.auth-sheet { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); padding: 20px 18px 14px; margin-top: 20px; display: flex; flex-direction: column; gap: 10px; animation: rise .3s ease-out .08s both; }
.btn-social { display: flex; align-items: center; justify-content: center; gap: 10px; width: 100%; padding: 12px 16px; font: inherit; font-size: .95rem; font-weight: 700; color: var(--ink); background: var(--card); border: 1.5px solid var(--line); border-radius: 999px; cursor: pointer; transition: background .15s, border-color .15s, transform .1s; }
.btn-social:hover { background: var(--cream); border-color: #d5cdbc; }
.btn-social:active { transform: scale(.98); }
.btn-social svg { flex: none; }
.auth-divider { display: flex; align-items: center; gap: 12px; color: var(--muted); font-size: .8rem; font-weight: 700; margin: 4px 0; }
.auth-divider::before, .auth-divider::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.auth-method { align-self: center; }
.auth-form { display: flex; flex-direction: column; gap: 10px; }
.auth-form input { font: inherit; font-size: .98rem; padding: 13px 16px; border: 1.5px solid var(--line); border-radius: 12px; background: var(--cream); text-align: center; }
.auth-form input:focus { outline: 2px solid var(--teal); outline-offset: 0; border-color: transparent; }
.auth-skip { align-self: center; font-size: .88rem; margin-top: 2px; }
/* T1234 A2: primary skip button for the no-provider fallback state. */
#auth-skip-primary { align-self: center; }
/* #1238 A5: Google sign-in button wrapper — centres the iframe inside the
   auth sheet and gives it the same vertical rhythm as a primary button. */
#google-signin-button {
    display: flex;
    justify-content: center;
    width: 100%;
}
.auth-fineprint { margin: 2px 0 0; text-align: center; font-size: .75rem; color: var(--muted); }
.auth-fineprint a { color: var(--teal-deep); }

.verify-mark { display: inline-block; width: 76px; height: 76px; border-radius: 50%; background: url("/static/icons/mark-fallback.png") no-repeat; background-size: 165%; background-position: 50% 22%; border: 3px solid var(--teal-soft); box-shadow: var(--shadow); }
.code-input { text-align: center; font-size: 1.6rem !important; font-weight: 800; letter-spacing: .35em; text-indent: .35em; padding: 12px 8px !important; }
.code-input::placeholder { letter-spacing: .2em; color: #c9c1b0; }
.verify-links { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.verify-links .btn-ghost:disabled { color: var(--green); text-decoration: none; cursor: default; }

.sheet { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); padding: 18px 16px; margin-top: 12px; display: flex; flex-direction: column; gap: 16px; }
.field { display: flex; flex-direction: column; gap: 6px; }
.field > span { font-size: .85rem; font-weight: 700; color: var(--teal-deep); }
/* #1469 (design social-time-v1 §A A-1): the type list, not the element, was
   the bug — #circle-invite-email-input is type="email" and so rendered raw
   next to the styled type="text" name box beside it. Every text-entry type
   the app can plausibly use is listed here so the next one added does not
   re-open the same defect. */
.field input[type="text"],
.field input[type="number"],
.field input[type="email"],
.field input[type="tel"],
.field input[type="url"],
.field input[type="search"] { font: inherit; font-size: .95rem; padding: 11px 14px; border: 1.5px solid var(--line); border-radius: 12px; background: var(--cream); }
.field input:focus { outline: 2px solid var(--teal); outline-offset: 0; border-color: transparent; }
.segmented { display: flex; gap: 8px; flex-wrap: wrap; }
.segmented button { font: inherit; font-size: .88rem; font-weight: 700; color: var(--ink); background: var(--cream); border: 1.5px solid var(--line); border-radius: 999px; padding: 8px 14px; cursor: pointer; transition: border-color .15s, background .15s; }
.segmented button.selected { background: var(--teal-soft); border-color: var(--teal); color: var(--teal-deep); }
.kid-row { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.kid-row input { width: 100%; min-width: 0; font: inherit; font-size: .95rem; padding: 10px 12px; border: 1.5px solid var(--line); border-radius: 12px; background: var(--cream); }
.kid-row .kid-label { font-size: .85rem; font-weight: 600; color: var(--muted); flex: 1; }
.kid-row .remove-kid { font: inherit; font-size: .8rem; font-weight: 700; color: var(--muted); background: none; border: none; cursor: pointer; text-decoration: underline; }
/* #1386 + #1388: kid-row grid. #1388's JS emits SIX flat siblings per row —
   label | years-input | "yrs" | months-input | "mths" | name-input — so the
   template has six tracks, not the four the original #1386 spec assumed.
   (That mismatch was a ticket-authoring error, reconciled 2026-08-19.) */
#kids-list .kid-row, #profile-kids-list .kid-row {
    display: grid;
    grid-template-columns: auto 52px auto 52px auto minmax(0, 1fr);
    gap: 6px;
    align-items: center;
}
#kids-list .kid-row-unit, #profile-kids-list .kid-row-unit {
    font-size: .8rem;
    color: var(--muted);
    white-space: nowrap;
}
.app-nav .nav-short { display: none; }

@media (max-width: 400px) {
    #kids-list .kid-row-label, #profile-kids-list .kid-row-label {
        grid-column: 1 / -1;
    }
    /* T2356 / UX-18: measured at 320x844 with all four nav buttons visible,
       .brand-text was 15px wide (55 @360, 85 @390) -- the wordmark clipped at
       every small width -- while #plan-btn was 36px wide, under the 44px tap
       floor the rest of the app holds to. The nav is the only thing that can
       give: shorter labels (the accessible name stays on aria-label), a
       tighter gap, and the tagline dropped, which is the one piece of header
       text that is decorative rather than identity. Every nav button keeps a
       44px minimum in BOTH axes. */
    .tagline { display: none; }
    .app-header { gap: 5px; padding-left: 8px; padding-right: 8px; }
    .app-header .brand-mark { width: 32px; height: 32px; }
    /* The wordmark scales with the viewport instead of being ellipsised: it
       was clipped at 320, 360 AND 390 before this ticket, so the app had no
       legible identity on any common phone. Display type, so the tracking
       tightens with it rather than staying at the body value. */
    .wordmark { font-size: clamp(.88rem, 4.4vw, 1.2rem); letter-spacing: -.02em; }
    .app-nav { gap: 2px; }
    .app-nav button { min-width: 44px; padding: 6px 1px; font-size: .76rem; }
    .app-nav .nav-long { display: none; }
    .app-nav .nav-short { display: inline; }
}

.consent { display: flex; align-items: flex-start; gap: 8px; font-size: .85rem; color: var(--muted); }
.consent input { margin-top: 3px; accent-color: var(--teal); }
.consent input[type="checkbox"] {
    min-width: 24px;
    min-height: 24px;
    padding: 10px;
    margin: -10px 4px -10px -10px;
    box-sizing: content-box;
}
.consent a { display: inline-block; min-height: 24px; line-height: 24px; color: var(--teal-deep); }
.form-error { color: var(--danger); font-size: .85rem; font-weight: 700; min-height: 1em; margin: 0; }
.profile-actions { display: flex; gap: 10px; align-items: center; }
.profile-actions .btn-primary { flex: 1; }

/* #1386: minimum 44px interactive targets. Checkbox visuals stay compact
   (24x24) rather than scaling to 44 — they sit inside a wrapping label/chip
   that carries the larger hit area; everything else gets a real min-height. */
input[type="checkbox"] {
    width: 24px;
    height: 24px;
}
.segmented button,
.btn-ghost.small,
.remove-kid,
#weekend-select {
    min-height: 44px;
}

@media (min-width: 640px) {
    body { background: #f3ecdd; }
    .app-header { background: rgba(251, 247, 239, .97); }
    .app-header .brand-mark { width: 46px; height: 46px; }
    .app-main { background: var(--cream); border-left: 1px solid var(--line); border-right: 1px solid var(--line); padding: 24px 28px 110px; }
    .composer { border-left: 1px solid var(--line); border-right: 1px solid var(--line); }
    .card-photo { height: 190px; }
    .card-body { padding: 16px 20px 18px; }
    .block-grid button { min-height: 62px; }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation: none !important; transition: none !important; }
}

.weekend-picker { display: flex; align-items: center; gap: 10px; margin: 0 0 12px; color: var(--teal-deep); font-size: .86rem; font-weight: 800; }
.weekend-picker select { flex: 1; min-width: 0; font: inherit; color: var(--ink); background: var(--card); border: 1.5px solid var(--line); border-radius: 999px; padding: 9px 34px 9px 13px; }
.weekend-picker select:focus { outline: 2px solid var(--teal); outline-offset: 1px; }

/* #302: large "Find activities" submit button */
#submit-btn {
    display: block;
    width: 100%;
    padding: 16px 20px;
    font: inherit;
    font-size: 1.05rem;
    font-weight: 800;
    color: #fff;
    background: var(--orange);
    border: none;
    border-radius: 999px;
    cursor: pointer;
    transition: background .15s, transform .1s;
}
#submit-btn:hover { background: var(--orange-deep); }
#submit-btn:active { transform: scale(.98); }

/* #302: plan detail inputs (location / budget)
   #1460: width:100% + min-width:0 so these size to the .plan-detail-body
   wrapper (with its own box-sizing: border-box) instead of overflowing it. */
#plan-detail-panel input[type="text"],
#plan-detail-panel input[type="number"],
#plan-detail-panel input[type="email"],
#plan-detail-panel input[type="tel"],
#plan-detail-panel input[type="url"],
#plan-detail-panel input[type="search"],
#plan-detail-panel select {
    font: inherit;
    font-size: .95rem;
    padding: 11px 14px;
    border: 1.5px solid var(--line);
    border-radius: 12px;
    background: var(--cream);
    width: 100%;
    min-width: 0;
}
#plan-detail-panel input:focus,
#plan-detail-panel select:focus {
    outline: 2px solid var(--teal);
    outline-offset: 0;
    border-color: transparent;
}

/* #556: free-only + budget on one row, half width each */
.plan-row-split { display:flex; align-items:center; gap:12px; }
.plan-row-split > * { flex:1 1 50%; min-width:0; }

/* #561: deterministic Refine button, plan-detail-panel */
#plan-refine-btn { display: block; width: 100%; min-height: 56px; margin-top: 10px; }

/* #563: activity-type multi-select (fed by GET /activities/types).
   T1242: broadened from #plan-activity-type.type-select to the bare class so
   #plan-detail-panel can reuse the same disclosure styling without a new class. */
.type-select {
    border: 1.5px solid var(--line);
    border-radius: 12px;
    background: var(--cream);
}
.type-select summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    min-height: 56px;
    padding: 11px 14px;
    font: inherit;
    font-size: .95rem;
    cursor: pointer;
    list-style: none;
}
.type-select summary::-webkit-details-marker { display: none; }
.type-select-summary { color: var(--muted); font-size: .85rem; font-weight: 600; }
.type-select-options {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 0 14px 14px;
    max-height: 40vh;
    overflow-y: auto;
    overscroll-behavior: contain;
}
.type-select-options label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: .88rem;
    font-weight: 700;
    color: var(--ink);
    background: var(--card);
    border: 1.5px solid var(--line);
    border-radius: 999px;
    padding: 8px 14px;
    cursor: pointer;
    min-width: 0;
}
.type-select-options input[type="checkbox"] {
    accent-color: var(--teal);
}

/* T2357 / D-FT6: the type chips are a curated 11-bucket set, so they can be
   denser than the generic .type-select-options chip and fit two per row at
   390px — 6 rows instead of 11, inside the same 40vh cap. Scoped to the plan
   control so the What's On suburb chips keep the roomier default. */
#plan-activity-type-options {
    gap: 6px;
}
#plan-activity-type-options label {
    flex: 0 0 calc(50% - 3px);
    justify-content: flex-start;
    font-size: .84rem;
    padding: 9px 10px;
    min-height: 44px;
}
/* Two columns at 390px means a long label wraps to a second line rather than
   being truncated — the parent must be able to read the whole bucket. */
#plan-activity-type-options label span {
    white-space: normal;
    line-height: 1.25;
}

/* #422: custom suburb combobox (replaces native datalist) */
.combobox {
    position: relative;
}
.combobox-list {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    margin: 0;
    padding: 4px;
    list-style: none;
    background: var(--card);
    border: 1.5px solid var(--line);
    border-radius: 12px;
    box-shadow: var(--shadow);
    max-height: 240px;
    overflow-y: auto;
    z-index: 40;
}
.combobox-list li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 9px 12px;
    border-radius: 8px;
    font-size: .95rem;
    cursor: pointer;
}
.combobox-list li.active,
.combobox-list li:hover {
    background: var(--teal-soft);
}
.combobox-name {
    color: var(--ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.combobox-postcode {
    margin-left: auto;
    flex: 0 0 auto;
    color: var(--muted);
    font-size: .85rem;
    font-variant-numeric: tabular-nums;
}

/* #302: events filter container */
.events-filter {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    padding: 14px 16px;
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    margin-bottom: 16px;
}
.events-filter label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: .88rem;
    font-weight: 700;
    color: var(--teal-deep);
}
/* #565: single range-calendar control (from/to date inputs are now hidden;
   values are still ISO YYYY-MM-DD strings feeding the same query contract). */
.daterange { position: relative; }
.daterange-trigger {
    display: flex;
    align-items: center;
    min-height: 56px;
    font: inherit;
    font-size: .9rem;
    font-weight: 700;
    color: var(--ink);
    padding: 8px 14px;
    border: 1.5px solid var(--line);
    border-radius: 12px;
    background: var(--cream);
    cursor: pointer;
}
.daterange-trigger:focus, .daterange-trigger:focus-visible {
    outline: 2px solid var(--teal);
    outline-offset: 0;
    border-color: transparent;
}
.daterange-popover {
    position: absolute;
    z-index: 30;
    top: calc(100% + 8px);
    left: 0;
    /* 348 = 7 cells x 44 (the tap-target floor) + 6 x 2 gap + 24 padding + 2 border.
       At 300 the grid overflowed its own popover by 46px. */
    width: min(348px, 90vw);
    /* was max-width:100%, which resolved against .daterange -- a ~99px flex item in
       .events-filter -- so it beat the width above and clipped the desktop calendar
       to 99px for a grid needing 320px. A popover escapes its anchor by design; cap
       it against the viewport instead. */
    max-width: 90vw;
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 12px;
}
.daterange-nav { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.daterange-month-label { font-weight: 800; font-size: .92rem; }
.daterange-nav-btn {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    border: none;
    background: transparent;
    color: var(--teal-deep);
    font-size: 1.1rem;
    cursor: pointer;
}
.daterange-nav-btn:hover { background: var(--teal-soft); }
.daterange-weekdays, .daterange-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 2px;
}
.daterange-weekdays span {
    text-align: center;
    font-size: .75rem;
    font-weight: 700;
    color: var(--muted);
    padding: 4px 0;
}
.daterange-day {
    font: inherit;
    font-size: .85rem;
    aspect-ratio: 1;
    /* 44px, not 40 -- #471's WCAG pass set that floor everywhere else but missed
       this cell. Mis-taps on a 40px target are part of "cannot select start and
       end date". 6 rows x 44 + chrome fits inside the 70vh sheet. */
    min-height: 44px;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--ink);
    cursor: pointer;
}
.daterange-day:hover:not(:disabled) { background: var(--teal-soft); }
.daterange-day.is-past { color: #7d7565; cursor: default; }
.daterange-day.is-in-range { background: var(--teal-soft); border-radius: 0; }
.daterange-day.is-endpoint { background: var(--teal); color: #fff; font-weight: 800; }
.daterange-actions { display: flex; align-items: center; justify-content: space-between; margin-top: 8px; }
.daterange-actions .btn-primary {
    width: auto;
    padding: 8px 18px;
    font-size: .88rem;
}

/* D-DR1: sheet header (title + close) and in-progress hint — shared by the mobile
   bottom sheet and the desktop popover. */
.daterange-sheet-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 8px;
}
.daterange-sheet-title {
    margin: 0;
    font-size: .95rem;
    font-weight: 800;
    color: var(--ink);
}
.daterange-close-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--teal-deep);
    font-size: 1.2rem;
    line-height: 1;
    cursor: pointer;
}
.daterange-close-btn:hover { background: var(--teal-soft); }
.daterange-hint {
    margin: 0 0 8px;
    font-size: .8rem;
    font-weight: 600;
    color: var(--teal-deep);
}

/* Desktop has no scrim (D-DR1 keeps the anchored popover + its outside-click
   dismissal); the element still exists in markup, so keep it out of the flow. */
.daterange-scrim { display: none; }

/* D-DR1: mobile treatment — content-sized bottom sheet over a dimmed scrim. Replaces
   #894's full-viewport sheet (position:fixed / inset:0 / height:100vh), which combined
   with a flex:1 day grid to stretch six rows to fill the screen and inflate every
   .daterange-day cell (aspect-ratio: 1) along with it. */
@media (max-width: 640px) {
    .daterange-trigger {
        min-width: 50%;
    }
    .daterange-scrim {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 25;
        background: rgba(23, 69, 76, .45);
    }
    .daterange-popover {
        position: fixed;
        top: auto;
        left: 0;
        right: 0;
        bottom: 0;
        width: 100vw;
        max-width: 100vw;
        max-height: 70vh;
        border-radius: var(--radius) var(--radius) 0 0;
        overflow-y: auto;
        display: flex;
        flex-direction: column;
        padding: calc(12px + env(safe-area-inset-top, 0px)) 16px calc(16px + env(safe-area-inset-bottom, 0px));
    }
    .daterange-popover .daterange-nav { margin-bottom: 16px; }
    .daterange-popover .daterange-actions {
        flex: none;
        padding-top: 16px;
        border-top: 1px solid var(--line);
        margin-top: 12px;
    }
}

/* #302: kid select list */
.kid-select-list {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 10px 0;
}
.kid-select-list label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: .88rem;
    font-weight: 700;
    color: var(--ink);
    background: var(--cream);
    border: 1.5px solid var(--line);
    border-radius: 999px;
    padding: 8px 14px;
    cursor: pointer;
}
.kid-select-list input[type="checkbox"] {
    accent-color: var(--teal);
}

/* #566 / #894: What's On hub (Area) dropdown + suburb multi-select selector.
   Reuses the kid-select chip visual for the suburb list; suburb dropdown
   clones the existing type-select disclosure pattern. */
.events-hub-field select {
    font: inherit;
    font-size: .9rem;
    font-weight: 700;
    color: var(--ink);
    padding: 8px 12px;
    min-height: 40px;
    border: 1.5px solid var(--line);
    border-radius: 12px;
    background: var(--cream);
    cursor: pointer;
}
/* #894: suburb dropdown replaces the block — uses the same type-select classes
   so summary/options panel reuse existing styles. */
.events-suburb-select {
    flex-basis: 100%;
}
.events-suburb-select[hidden] { display: none; }
.events-suburb-select summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    min-height: 56px;
    padding: 11px 14px;
    font: inherit;
    font-size: .95rem;
    cursor: pointer;
    list-style: none;
}
.events-suburb-select summary::-webkit-details-marker { display: none; }
/* Suburb list: chip-style multi-select inside the dropdown. */
#events-suburb-list {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 0 14px 14px;
    max-height: 44vh;
    overflow-y: auto;
    overscroll-behavior: contain;
}
#events-suburb-list .suburb-all {
    flex-basis: 100%;
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--surface, #fff);
    border-color: var(--teal);
}
/* T2357 / UX-1: type-to-filter row above the suburb list. The combobox list
   itself reuses .combobox / .combobox-list (240px cap) — no new component. */
.events-suburb-search {
    padding: 0 14px 10px;
}
.events-suburb-search input {
    width: 100%;
    min-height: 44px;
}
/* A chosen suburb: a removable chip, not a row in a 535-item list. It is a
   <span> (not a <label>, so the remove button can't toggle the checkbox), so
   it restates the .type-select-options label pill rather than inheriting it. */
.suburb-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: .88rem;
    font-weight: 700;
    color: var(--ink);
    background: var(--card);
    border: 1.5px solid var(--line);
    border-radius: 999px;
    padding: 8px 10px 8px 14px;
    min-width: 0;
    max-width: 100%;
}
.suburb-chip-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.suburb-chip-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    /* 44px effective target without a 44px visible glyph (same trick as the
       T2352 consent checkbox). */
    padding: 8px;
    margin: -8px;
    box-sizing: content-box;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--muted);
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
}
.suburb-chip-remove:hover,
.suburb-chip-remove:focus-visible {
    color: var(--ink);
}
/* Feedback on the press, not on the release. */
.suburb-chip-remove:active,
.type-select-options label:active {
    transform: scale(.97);
    transition: transform 100ms ease-out;
}
@media (prefers-reduced-motion: reduce) {
    .suburb-chip-remove:active,
    .type-select-options label:active {
        transform: none;
    }
}
.suburb-select-loading {
    flex-basis: 100%;
    padding: 10px 4px;
    color: var(--muted);
    font-size: .88rem;
}

.combobox input {
    width: 100%;
}

/* room for the weather icon */
.block-grid button {
    padding-bottom: 20px;
}

/* #725: locked band social actions */
.locked-action {
    margin-left: 4px;
}
.locked-action:disabled {
    opacity: .5;
    cursor: default;
}
.invite-along-btn {
    color: var(--orange-deep);
}
.invite-along-btn:hover {
    background: var(--orange-soft);
}

/* #725: invite-along picker (inside locked card) */
.invite-picker {
    padding: 10px 0 0;
    border-top: 1px solid var(--line);
    animation: rise .22s ease-out both;
}
.invite-picker-label {
    margin: 0 0 6px;
    font-size: .84rem;
    font-weight: 700;
    color: var(--muted);
}
.invite-picker-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.invite-picker-item {
    align-self: flex-start;
    font: inherit;
    font-size: .88rem;
    font-weight: 700;
    color: var(--ink);
    background: var(--cream);
    border: 1.5px solid var(--line);
    border-radius: 999px;
    padding: 8px 14px;
    cursor: pointer;
    transition: border-color .15s, background .15s;
}
.invite-picker-item:hover {
    border-color: var(--teal);
    background: var(--teal-soft);
}
.invite-picker-item:disabled {
    opacity: .5;
    cursor: default;
}
.invite-picker-cancel {
    margin-top: 6px;
}
.invite-error {
    margin: 6px 0 0;
    font-size: .82rem;
    font-weight: 700;
    color: var(--teal-deep);
}

/* #726: Your circle card (Profile panel) */
.circle-card {
    margin-top: 20px;
    padding-top: 16px;
    border-top: 1px solid var(--line);
}
.circle-card h3 {
    margin: 0 0 10px;
    font-size: .95rem;
    font-weight: 800;
    color: var(--teal-deep);
}
.circle-row {
    background: var(--cream);
    border: 1.5px solid var(--line);
    border-radius: 12px;
    padding: 4px;
}
.circle-row-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    min-width: 0;
}
.circle-row-name {
    font-weight: 700;
    font-size: .9rem;
    color: var(--ink);
    overflow-wrap: anywhere;
    min-width: 0;
}
.circle-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    font-size: .78rem;
    font-weight: 800;
    padding: 4px 11px;
    border-radius: 999px;
    white-space: nowrap;
}
.circle-chip-pending {
    background: var(--orange-soft);
    color: var(--orange-deep);
}
.circle-chip-connected {
    background: var(--teal-soft);
    color: var(--teal-deep);
}
.circle-chip-expired {
    background: var(--line);
    color: var(--muted);
}
.circle-row-meta {
    display: block;
    font-size: .82rem;
    color: var(--muted);
    overflow-wrap: anywhere;
}
.circle-row-pending-actions,
.circle-row-incoming-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.circle-row-pending-actions > *,
.circle-row-incoming-actions > * {
    flex: 1 1 auto;
    min-width: 0;
    text-align: center;
}
/* .btn-ghost.small already carries min-height: 44px (#1386), but an <a> is
   inline by default so the min-height would never take. The mailto: action is
   an anchor, so give anchor-buttons the same real hit area as the buttons
   beside them. */
a.btn-ghost {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    line-height: 1.2;
}
.circle-row-incoming-actions .btn-primary {
    width: auto;
    padding: 8px 14px;
    font-size: .85rem;
    min-height: 44px;
}
/* Nothing in the card may establish a width floor wider than the viewport. */
.circle-card,
.circle-row {
    min-width: 0;
    max-width: 100%;
}
.circle-empty {
    font-size: .88rem;
    color: var(--muted);
    margin: 0 0 10px;
}

/* #726: circle-invite landing panel (/?circle=<token>) */
.circle-invite-explainer {
    list-style: none;
    margin: 0 0 18px;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.circle-invite-explainer li {
    font-size: .88rem;
    color: var(--muted);
    padding-left: 18px;
    position: relative;
}
.circle-invite-explainer li::before {
    content: "\2726";
    position: absolute;
    left: 0;
    color: var(--gold);
}
#circle-invite-decline-btn {
    display: block;
    width: 100%;
    text-align: center;
}

.btn-secondary.small { padding: 6px 14px; font-size: .85rem; }

/* CF-5 (#1313): Suggest an activity — header button + sheet form */
.suggest-btn { margin-left: 4px; }
.suggest-sheet textarea {
    font: inherit;
    font-size: .95rem;
    padding: 11px 14px;
    border: 1.5px solid var(--line);
    border-radius: 12px;
    background: var(--cream);
    resize: vertical;
}
.suggest-sheet textarea:focus {
    outline: 2px solid var(--teal);
    outline-offset: 0;
    border-color: transparent;
}
.card-status {
    margin: 4px 0 0;
    font-size: .88rem;
    font-weight: 700;
    color: var(--green);
    min-height: 1em;
}

/* #1239: profile identity header + sign-out + delete-account */
.profile-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 12px;
    padding: 14px 16px;
    background: var(--teal-soft);
    border-radius: var(--radius);
}
.profile-identity-info {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.profile-identity-info strong {
    font-size: .95rem;
    color: var(--ink);
}
.profile-signin-method {
    font-size: .78rem;
    color: var(--muted);
    font-weight: 600;
}
.signout-btn {
    flex: none;
    white-space: nowrap;
}
.profile-logged-out {
    margin-bottom: 12px;
    padding: 14px 16px;
    background: var(--cream);
    border: 1.5px solid var(--line);
    border-radius: var(--radius);
    font-size: .92rem;
}
.profile-logged-out p {
    margin: 0;
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}
/* Visually separated danger zone for delete account */
.profile-danger-zone {
    margin-top: 24px;
    padding-top: 18px;
    border-top: 2px solid var(--line);
}
.profile-danger-zone h3 {
    margin: 0 0 6px;
    font-size: .95rem;
    font-weight: 800;
    color: var(--danger);
}
.profile-danger-description {
    margin: 0 0 12px;
    font-size: .85rem;
    color: var(--muted);
}
.btn-danger {
    display: inline-block;
    padding: 10px 18px;
    background: transparent;
    color: var(--danger);
    border: 1.5px solid var(--danger);
    border-radius: 999px;
    font: inherit;
    font-size: .92rem;
    font-weight: 700;
    cursor: pointer;
    transition: background .15s, transform .1s;
}
.btn-danger:hover {
    background: var(--danger);
    color: #fff;
}
.btn-danger:disabled {
    opacity: .5;
    cursor: default;
}
.btn-danger:active {
    transform: scale(.98);
}
/* Two-step delete confirmation */
.profile-delete-steps {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-bottom: 6px;
}

/* #728: nudge proposal card + Plans screen (design §3.2, §3.4) */
.proposal-card .proposal-household {
    margin: 2px 0 12px;
    font-size: .88rem;
    font-weight: 700;
    color: var(--teal-deep);
}
.proposal-card .card-body { padding: 16px; }
.proposal-card .actions { display: flex; gap: 8px; }
.proposal-card .actions .btn-primary { width: auto; flex: 1; }
.proposal-dismissed {
    margin: 0;
    font-size: .88rem;
    color: var(--muted);
}
.reveal-band { flex-wrap: wrap; }
.reveal-band-actions {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}
.reveal-band-actions a,
.reveal-band-actions button {
    flex: none;
    font-size: .85rem;
    font-weight: 700;
}
.reveal-overflow-btn {
    text-decoration: none;
    font-size: 1.1rem;
    padding: 4px 8px;
}
.plan-called-off { color: var(--danger); }
.still-coming-row {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid #d3e8d4;
}
.still-coming-label {
    font-size: .85rem;
    font-weight: 700;
    color: var(--green);
    flex: 1 0 auto;
}

/* #728: Plans entry card (above the block picker) */
.plans-entry-card { margin: 0 0 16px; }
.plans-entry-card .btn-secondary { width: 100%; }

/* #728: Plans screen */
.plans-section-heading {
    margin: 0 0 10px;
    font-size: .95rem;
    font-weight: 800;
    color: var(--teal-deep);
}
#plans-joint-section { margin-bottom: 24px; }
.plans-joint-item .locked-band {
    border-radius: var(--radius);
    border: 1px solid #d3e8d4;
    border-top: 1px solid #d3e8d4;
    margin-bottom: 12px;
    flex-direction: column;
    align-items: flex-start;
}

/* CF-8: report-a-problem button (ghost, fits actions row) */
.report-problem-btn {
    font-size: .82rem;
    color: var(--muted);
    text-decoration-color: var(--line);
}
.report-problem-btn:hover {
    color: var(--teal-deep);
    text-decoration-color: var(--teal);
}
.report-problem-btn:disabled {
    opacity: .6;
    cursor: default;
    text-decoration: none;
    color: var(--green);
}

/* CF-8: report-a-problem toast overlay */
.report-toast {
    position: fixed;
    left: 50%;
    bottom: 80px;
    z-index: 100;
    transform: translateX(-50%);
    background: var(--green);
    color: #fff;
    font-weight: 700;
    font-size: .88rem;
    padding: 10px 22px;
    border-radius: 999px;
    box-shadow: var(--shadow);
    animation: toastIn .25s ease-out both;
    pointer-events: none;
}
@keyframes toastIn {
    from { opacity: 0; transform: translateX(-50%) translateY(12px); }
    to { opacity: 1; transform: translateX(-50%) translateY(0); }
}

/* F3/F5: expanded-disclosure and inline-form content rhythm.
   #plan-detail-panel and .circle-invite-form both hold a stack of labelled controls;
   both get the .type-select-options horizontal padding and a 12px vertical rhythm.
   #1460: Chromium >=131 lays out <details> as summary + an internal
   ::details-content box that isn't a normal child of the <details> element, so
   flex/row-gap/margin rules on the open panel selector or its > :not(summary)
   children never reach the inputs in Chromium (they only worked in other
   engines — the T1423/PR#485 fix regressed on Chrome). The rhythm now lives on
   a real child, .plan-detail-body, wrapped around everything but <summary>. */
.plan-detail-body { display: flex; flex-direction: column; row-gap: 12px; padding: 0 14px 14px; }
.circle-invite-form { display: flex; flex-direction: column; gap: 12px; margin: 12px 0; }

/* Same reason as a.btn-ghost above: an <a> is inline, so the button padding
   and min-height never take. The mailto: "Email them" action is an anchor. */
a.btn-primary.small {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    line-height: 1.2;
    text-decoration: none;
}

/* #1386 follow-up (2026-08-19 consolidated verification): the suburb checkboxes
   are 24x24 by the input[type=checkbox] rule, but flex was compressing them to
   21-23px wide at 320px. Pin the box so the target holds at every width. */
.suburb-cb { flex: none; }

/* ---------------------------------------------------------------------------
   #1473 (D-S3a): calendar sync — the card, the busy tile, the busy×mark ask.
   Everything here is inert until app.js unhides #calendar-card / adds .busy,
   which it only does with calendar-sync live, so a flags-off grid is
   byte-for-byte the 2x2 of bare tiles it has always been.
   --------------------------------------------------------------------------- */
.calendar-confirm {
    margin-top: 8px;
    padding: 10px 12px;
    background: var(--cream);
    border: 1.5px solid var(--line);
    border-radius: 12px;
}
.calendar-confirm p {
    margin: 0 0 8px;
    font-size: .82rem;
    color: var(--ink);
    overflow-wrap: anywhere;
}
.calendar-confirm-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.calendar-confirm-actions > * {
    min-height: 44px;
}
#calendar-card,
#calendar-disconnected,
#calendar-connected {
    min-width: 0;
    max-width: 100%;
}
#calendar-connect-google-btn {
    width: 100%;
    min-height: 44px;
    overflow-wrap: anywhere;
}
#calendar-ics-save-btn,
#calendar-disconnect-btn {
    min-height: 44px;
}

/* The tile keeps its full 56px hit area and stays selectable: the calendar is
   a warning, not a lock (D-S3a two-factor rule). Hatch + muted ink is the
   whole signal, so `.selected` still wins on background and ring. */
.block-grid button[data-slot].busy {
    color: var(--muted);
    background-image: repeating-linear-gradient(
        45deg,
        transparent 0,
        transparent 5px,
        var(--line) 5px,
        var(--line) 7px
    );
}
.block-grid button[data-slot].selected.busy {
    background-color: var(--teal-soft);
    color: var(--ink);
}
.block-busy-label {
    font-size: .72rem;
    font-weight: 700;
    color: var(--muted);
    line-height: 1.2;
    overflow-wrap: anywhere;
}

.suggest-entry-row { margin-top: 16px; text-align: center; }


/* ── T2363 / UX-23: install affordance ──────────────────────────────────────
   OutingOwl has no app store, so this row is the whole install story. It is
   the quietest thing that can still be found: card weight, no colour of its
   own, and it only ever appears once — after a successful Lock it in
   (install-prompt.md D-IP2/D-IP3). Both controls clear the 44px floor the
   rest of the app holds to. */
.install-row {
    margin-top: 16px;
    padding: 14px;
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    opacity: 0;
    transform: translateY(6px);
    transition: opacity .32s ease-out, transform .32s cubic-bezier(.2, .7, .2, 1);
}
.install-row.is-shown {
    opacity: 1;
    transform: none;
}
.install-row-text {
    margin: 0;
    font-weight: 700;
    letter-spacing: -.005em;
}
.install-row-hint {
    margin: 6px 0 0;
    color: var(--muted);
    font-size: .9rem;
}
.install-row-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-top: 12px;
}
.install-row-actions button {
    min-height: 44px;
    min-width: 44px;
}
/* The row is an arrival, not a motion event — a cross-fade carries the same
   information without the rise. */
@media (prefers-reduced-motion: reduce) {
    .install-row {
        transform: none;
        transition: opacity .2s ease;
    }
}

/* #2365 / UX-6: in-context consent sheet for anonymous (Skip) sessions. */
.consent-dialog {
    width: min(420px, calc(100vw - 32px));
    padding: 24px;
    border: none;
    border-radius: var(--radius);
    background: var(--card);
    color: var(--ink);
    box-shadow: var(--shadow);
    font-family: var(--font);
}
.consent-dialog::backdrop {
    background: rgba(23, 69, 76, .45);
}
.consent-dialog h2 {
    margin: 0 0 8px;
    font-size: 1.2rem;
}
.consent-dialog p {
    margin: 0 0 12px;
    line-height: 1.45;
}
.consent-fineprint {
    font-size: .85rem;
    color: var(--muted);
}
.consent-actions {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 16px;
}
.consent-fineprint a {
    color: var(--teal);
}
