/* hausync — tokens, layout, components.
   Monochrome: white/black chrome, neutral grays, red/green/yellow only for meaning.
   Member identity colours are the one exception (rings, never fills).
   Mobile-first; dark via prefers-color-scheme; frosted glass only on floating chrome. */

/* ---------- tokens ---------- */
:root {
  color-scheme: light dark;
  /* chrome */
  --bg: #ffffff;
  --surface: #ffffff;
  --surface-2: #f4f4f4;
  --text: #111111;
  --text-muted: #5f5f5f;
  --border: #e3e3e3;
  --border-strong: #bdbdbd;
  --primary: #111111;
  --primary-text: #ffffff;
  /* semantic */
  --danger: #b91c1c;
  --ok: #166534;
  --warn: #854d0e;
  --danger-bg: color-mix(in srgb, var(--danger) 12%, var(--surface));
  --ok-bg: color-mix(in srgb, var(--ok) 12%, var(--surface));
  --warn-bg: color-mix(in srgb, var(--warn) 12%, var(--surface));
  /* identity */
  --member: var(--text-muted);
  /* frosted glass */
  --frost-bg: rgba(255, 255, 255, 0.72);
  --frost-edge: rgba(255, 255, 255, 0.9);
  --frost-blur: 16px;
  --scrim: rgba(0, 0, 0, 0.4);
  /* type */
  --font: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --fs-xs: 0.75rem;
  --fs-sm: 0.8125rem;
  --fs-md: 0.875rem;
  --fs-base: 1rem;
  --fs-lg: 1.125rem;
  --fs-xl: 1.25rem;
  --fs-2xl: 1.5rem;
  /* space, radius, elevation, motion */
  --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px; --space-5: 24px; --space-6: 32px;
  --r-sm: 6px; --r-md: 10px; --r-lg: 14px; --r-pill: 999px;
  --radius: var(--r-lg);
  --shadow-1: 0 4px 14px rgba(0, 0, 0, 0.14);
  --shadow-2: 0 8px 24px rgba(0, 0, 0, 0.16);
  --dur-1: 120ms;
  --dur-2: 200ms;
  --ease: cubic-bezier(0.2, 0, 0, 1);
  /* chrome geometry */
  --tabbar-h: 56px;
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-top: env(safe-area-inset-top, 0px);
  --topbar-h: calc(52px + var(--safe-top));
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #000000;
    --surface: #111111;
    --surface-2: #1c1c1c;
    --text: #f2f2f2;
    --text-muted: #a3a3a3;
    --border: #2e2e2e;
    --border-strong: #4a4a4a;
    --primary: #f2f2f2;
    --primary-text: #000000;
    --danger: #f87171;
    --ok: #4ade80;
    --warn: #fbbf24;
    --frost-bg: rgba(0, 0, 0, 0.6);
    --frost-edge: rgba(255, 255, 255, 0.08);
    --scrim: rgba(0, 0, 0, 0.6);
    --shadow-1: none;
    --shadow-2: none;
  }
}

/* ---------- base ---------- */
* { box-sizing: border-box; }
html { height: 100%; -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg); color: var(--text); font-family: var(--font); font-size: var(--fs-base); line-height: 1.5;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation; /* no double-tap zoom: this is an app, not a page */
}
/* ---------- app shell ----------
   The app is a fixed full-height column: top bar, scrolling pane, tab bar. Nothing in the chrome
   is position:fixed against the iOS viewport any more (that floated and drifted on phones); only
   the middle pane scrolls. --vvh mirrors visualViewport.height so the shell shrinks to the visible
   area when the keyboard is up. Landing and legal pages stay ordinary scrolling documents.

   INSTALLED (standalone) iOS, black-translucent status bar, viewport-fit=cover: WebKit (iOS 26)
   draws the page from the true top of the screen but subtracts the top safe-area inset from
   100%, 100dvh, 100svh, innerHeight and visualViewport.height. Sizing the shell with any of those
   strands a status-bar-tall dead band under the tab bar (the recurring "tab bar sits too high"
   bug). Only 100lvh reports the physical screen height, so in display-mode: standalone the
   shell is 100lvh tall and --vp-gap (= 100lvh - 100dvh, 0 where WebKit is sane) pulls the
   position:fixed chrome (toasts, new-messages pill) down by the same amount. In a browser tab
   100dvh is correct and --vp-gap stays 0. */
html { height: 100%; }
:root { --vp-gap: 0px; }
body:not(.landing):not(.legal) {
  height: 100dvh; height: var(--vvh, 100dvh);
  overflow: hidden; display: flex; flex-direction: column;
}
@media (display-mode: standalone), (display-mode: fullscreen) {
  :root { --vp-gap: calc(100lvh - 100dvh); }
  body:not(.landing):not(.legal) { height: 100lvh; height: var(--vvh, 100lvh); }
}
body:not(.landing):not(.legal) > .page {
  flex: 1 1 auto; min-height: 0; width: 100%;
  overflow-y: auto; overflow-x: hidden; -webkit-overflow-scrolling: touch; overscroll-behavior-y: contain;
}
body.landing { padding-bottom: 0; }
body.legal { padding-bottom: var(--space-6); }
[hidden] { display: none !important; }
a { color: var(--text); text-decoration: underline; text-underline-offset: 2px; text-decoration-color: var(--border-strong); }
a:hover { text-decoration-color: currentColor; }
h1, h2, h3 { margin: 0 0 var(--space-3); font-weight: 700; line-height: 1.2; letter-spacing: -0.01em; }
h2 { font-size: var(--fs-lg); }
h3 { font-size: var(--fs-base); }
p { margin: 0 0 var(--space-3); }
.muted { color: var(--text-muted); }
.small { font-size: var(--fs-md); }
.center { text-align: center; }
.grow { flex: 1 1 auto; min-width: 0; }
.num { font-variant-numeric: tabular-nums; }
code.code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 1.05rem; letter-spacing: 0.08em; background: var(--surface-2); padding: 2px 8px; border-radius: var(--r-sm); }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
.skip-link { position: absolute; left: var(--space-3); top: -100px; z-index: 100; padding: 8px 12px; background: var(--primary); color: var(--primary-text); border-radius: var(--r-md); text-decoration: none; }
.skip-link:focus { top: calc(var(--safe-top) + var(--space-3)); }

/* focus: maximal contrast ring, keyboard only */
:focus { outline: none; }
:focus-visible { outline: 2px solid var(--text); outline-offset: 2px; }
input:not([type=checkbox]):not([type=radio]):focus-visible, select:focus-visible, textarea:focus-visible { outline-offset: 1px; }
.btn-primary:focus-visible, .toast:focus-visible, .day--today .daynum:focus-visible { outline-color: var(--bg); outline-offset: -3px; }

/* frosted glass: floating chrome only */
.frost {
  background: var(--frost-bg);
  -webkit-backdrop-filter: blur(var(--frost-blur)) saturate(1.2);
  backdrop-filter: blur(var(--frost-blur)) saturate(1.2);
  box-shadow: inset 0 1px 0 var(--frost-edge);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .frost { background: var(--bg); }
}
@media (prefers-reduced-transparency: reduce) {
  .frost { background: var(--bg); -webkit-backdrop-filter: none; backdrop-filter: none; }
}

/* ---------- top bar ---------- */
.topbar {
  position: relative; flex: 0 0 auto; z-index: 20; display: flex; align-items: center; gap: var(--space-1);
  padding: var(--safe-top) var(--space-3) 0 var(--space-3);
  height: var(--topbar-h);
  border-bottom: 1px solid var(--border);
}
.topbar-title { font-size: var(--fs-lg); margin: 0; flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-left: var(--space-1); }
.topbar-back { border: 0; background: transparent; color: var(--text); width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center; margin-left: -8px; border-radius: var(--r-md); cursor: pointer; }
.topbar-back svg { width: 24px; height: 24px; }
.topbar-actions { display: flex; gap: var(--space-1); align-items: center; }
.topbar-actions .btn { min-height: 40px; }
#progress { position: fixed; left: 0; right: 0; top: var(--topbar-h); height: 2px; background: var(--text); transform: scaleX(0); transform-origin: left; opacity: 0; z-index: 21; transition: transform var(--dur-2) var(--ease), opacity var(--dur-2); pointer-events: none; }
#progress.htmx-request { transform: scaleX(0.7); opacity: 1; }
.conn-pill { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border: 1px solid var(--text); border-radius: var(--r-pill); font-size: var(--fs-sm); white-space: nowrap; }
.conn-pill::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--warn); }

/* ---------- page + cards ---------- */
.page { --page-max: 720px; padding: var(--space-4) max(var(--space-4), calc((100% - var(--page-max)) / 2)); display: flex; flex-direction: column; gap: var(--space-4); }
body:not(.landing):not(.legal):not(.chat-page) > .page { padding-bottom: var(--space-5); }
body.auth .topbar { display: none; }
body.auth .page { --page-max: 420px; padding-top: var(--space-5); }
.auth-brand { display: flex; justify-content: center; }
.auth-brand a { display: inline-flex; align-items: center; gap: var(--space-2); min-height: 44px; padding: 0 var(--space-2); font-weight: 700; font-size: var(--fs-lg); color: var(--text); text-decoration: none; }
.auth-brand .i { display: inline-flex; }
.auth-brand .i svg { width: 24px; height: 24px; }
.auth-step { margin: 0; color: var(--text-muted); font-size: var(--fs-md); }
body.landing .topbar { display: none; }
body.landing .page { max-width: none; padding: 0; gap: 0; }
body.legal .page { max-width: 680px; }
.legal-h1 { font-size: var(--fs-2xl); margin-bottom: var(--space-1); }
.legal-updated { margin-top: 0; margin-bottom: var(--space-4); }
.legal h2 { margin-top: var(--space-5); font-size: var(--fs-lg); }
.legal ul { margin: 0 0 var(--space-3); padding-left: 1.25em; }
.legal li { margin-bottom: var(--space-1); }
.legal-footer { margin-top: var(--space-6); padding-top: var(--space-4); border-top: 1px solid var(--border); }
.card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); padding: var(--space-4); }
.card-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-3); }
.card-head h2 { margin: 0; }
.form .card-head { margin-bottom: 0; }
.card-link { font-size: var(--fs-md); color: var(--text-muted); }
a.card { text-decoration: none; display: block; transition: background-color var(--dur-1) var(--ease); }
a.card:active { background: var(--surface-2); }
.list { list-style: none; margin: 0 0 var(--space-3); padding: 0; display: flex; flex-direction: column; }
.list:last-child { margin-bottom: 0; }
.row { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) 0; border-top: 1px solid var(--border); min-height: 48px; }
.row:first-child { border-top: 0; }
.row-wrap { flex-wrap: wrap; }
.row-form { display: flex; gap: var(--space-2); align-items: center; flex-wrap: wrap; }
.row > a.grow, .row-title, .list a.grow { text-decoration: none; color: var(--text); }
.row-title { display: block; font-weight: 600; }
.inst-name { display: block; font-weight: 600; }
.row-sub { display: block; color: var(--text-muted); font-size: var(--fs-md); }
.list-links .row { color: var(--text); font-weight: 500; text-decoration: none; }
.list-links .row::after, .chev::after {
  content: ""; margin-left: auto; width: 20px; height: 20px; flex: 0 0 auto; background: var(--text-muted);
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M9 6l6 6-6 6'/></svg>") center / contain no-repeat;
  mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M9 6l6 6-6 6'/></svg>") center / contain no-repeat;
}
.avatar-row { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.greeting { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: 0 var(--space-1); }
.greeting-name { font-size: var(--fs-xl); font-weight: 700; display: block; }
hr { border: 0; border-top: 1px solid var(--border); margin: var(--space-2) 0; }

/* ---------- invites (code, buttons, QR on demand) ---------- */
.invite { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-3) 0; border-top: 1px solid var(--border); }
.invite:first-child { border-top: 0; }
.invite-code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: var(--fs-2xl); font-weight: 700; letter-spacing: 0.12em; }
.invite-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-1); }
.invite-qr { width: 200px; max-width: 100%; margin-top: var(--space-2); padding: 8px; background: #fff; border: 1px solid var(--border); border-radius: var(--r-md); }
.invite-qr svg { display: block; width: 100%; height: auto; }
.invite-qr svg path { fill: #000; }
.invite-form h3 { margin: var(--space-2) 0 0; }

/* ---------- forms ---------- */
.form { display: flex; flex-direction: column; gap: var(--space-3); }
.field { display: flex; flex-direction: column; gap: var(--space-1); font-size: var(--fs-md); color: var(--text-muted); }
.field .hint { font-size: var(--fs-sm); }
.field .readonly { margin: 0; color: var(--text); display: flex; flex-direction: column; gap: 2px; }
.field .readonly .hint { color: var(--text-muted); }
.field-check { display: flex; align-items: flex-start; gap: var(--space-2); min-height: 44px; font-size: var(--fs-md); color: var(--text-muted); cursor: pointer; }
.field-check input[type=checkbox] { flex: 0 0 auto; margin-top: 2px; }
/* The label text is one wrapping block beside the box; inline links wrap with it instead of
   becoming separate flex items (the consent sentence used to break into columns). */
.field-check > span { flex: 1 1 auto; min-width: 0; }
fieldset.field { border: 0; padding: 0; margin: 0; min-width: 0; }
fieldset.field legend { padding: 0; margin-bottom: var(--space-1); }
.grid-2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-3); }
.grid-2 > * { min-width: 0; }
.field { min-width: 0; }
/* iOS gives date/time/select controls an intrinsic width that ignores the column and pours out of
   the card; strip the native appearance and let them fill their track. */
input[type=date], input[type=time], input[type=datetime-local], input[type=month], select {
  -webkit-appearance: none; appearance: none; min-width: 0; max-width: 100%; width: 100%; display: block;
}
input[type=date]::-webkit-date-and-time-value, input[type=time]::-webkit-date-and-time-value { text-align: left; min-height: 1.5em; }
input, select, textarea, button { font: inherit; color: inherit; }
input:not([type=checkbox]):not([type=radio]), select, textarea {
  background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--r-md); padding: 10px 12px; min-height: 44px; width: 100%; color: var(--text);
  transition: border-color var(--dur-1) var(--ease);
}
input:not([type=checkbox]):not([type=radio]):focus-visible, select:focus-visible, textarea:focus-visible { border-color: var(--text); }
input[aria-invalid="true"], select[aria-invalid="true"], textarea[aria-invalid="true"] { border-color: var(--danger); }
input::placeholder, textarea::placeholder { color: var(--text-muted); opacity: 0.8; }
input[type=checkbox], input[type=radio] { width: 20px; height: 20px; margin: 0 6px 0 0; accent-color: var(--text); }
.row-form input:not([type=checkbox]), .row-form select { width: auto; flex: 1 1 8rem; min-width: 0; }
.input-sm { flex: 0 1 5rem; max-width: 6rem; }
.field-error { color: var(--danger); font-size: var(--fs-md); margin: 0; }
.flash { border-radius: var(--r-md); padding: var(--space-2) var(--space-3); margin-bottom: var(--space-3); display: flex; gap: var(--space-2); align-items: flex-start; }
.flash-error { background: var(--danger-bg); color: var(--danger); }
.flash-ok { background: var(--ok-bg); color: var(--ok); }
.flash-warn { background: var(--warn-bg); color: var(--warn); }
.flash-warn, .flash-ok, .flash-error { color: var(--text); border-left: 3px solid; }
.flash svg { width: 20px; height: 20px; flex-shrink: 0; margin-top: 2px; }
.flash-error { border-left-color: var(--danger); }
.flash-ok { border-left-color: var(--ok); }
.flash-warn { border-left-color: var(--warn); }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-1);
  border: 1px solid var(--border-strong); background: var(--surface); color: var(--text);
  border-radius: var(--r-md); padding: 8px 14px; min-height: 44px; cursor: pointer; font-weight: 600; white-space: nowrap;
  text-decoration: none; position: relative;
  transition: background-color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);
}
.btn:hover { background: var(--surface-2); }
.btn:active { transform: scale(0.98); }
.btn-primary { background: var(--primary); border-color: var(--primary); color: var(--primary-text); }
.btn-primary:hover { background: color-mix(in srgb, var(--primary) 88%, var(--bg)); }
.btn-ghost { background: transparent; border-color: transparent; }
.btn-danger { color: var(--danger); }
.btn-block { width: 100%; }
.btn-sm { min-height: 36px; padding: 4px 12px; font-size: var(--fs-md); }
.btn-icon { width: 44px; padding: 0; }
.btn-icon svg { width: 22px; height: 22px; }
@media (pointer: coarse) { .btn-sm { min-height: 44px; } }
.btn[disabled], .btn[aria-disabled="true"] { opacity: 0.45; pointer-events: none; }
.btn.is-on { background: var(--primary); border-color: var(--primary); color: var(--primary-text); }
button.link { background: none; border: 0; padding: 0; color: var(--text-muted); cursor: pointer; text-decoration: underline; text-underline-offset: 2px; font-size: inherit; font: inherit; }
button.link.danger { color: var(--danger); }

/* loading: button spinner (htmx adds .htmx-request to the form/button) */
.htmx-request .btn[type=submit], .btn.htmx-request { color: transparent !important; pointer-events: none; }
.htmx-request .btn[type=submit]::after, .btn.htmx-request::after {
  content: ""; position: absolute; width: 16px; height: 16px; left: calc(50% - 8px); top: calc(50% - 8px);
  border: 2px solid var(--text); border-right-color: transparent; border-radius: 50%;
  animation: spin 600ms linear infinite;
}
.htmx-request .btn-primary[type=submit]::after, .btn-primary.htmx-request::after { border-color: var(--primary-text); border-right-color: transparent; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- member identity ---------- */
.avatar {
  display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: 50%;
  background: var(--surface); color: var(--text); font-weight: 700; font-size: var(--fs-sm); flex: 0 0 auto;
  box-shadow: inset 0 0 0 2px var(--member);
}
.avatar.sm { width: 24px; height: 24px; font-size: 0.6rem; box-shadow: inset 0 0 0 2px var(--member); }
.chip { display: inline-flex; align-items: center; gap: 6px; padding: 2px 10px 2px 8px; border-radius: var(--r-pill); background: var(--surface-2); font-size: var(--fs-md); }
.chip::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--member); }
.chip .avatar { display: none; }
.badge { display: inline-block; min-width: 20px; padding: 0 7px; border-radius: var(--r-pill); background: var(--primary); color: var(--primary-text); font-size: var(--fs-xs); font-weight: 600; text-align: center; line-height: 20px; font-variant-numeric: tabular-nums; }
.badge-muted { background: var(--surface-2); color: var(--text-muted); }
.swatches { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.swatch { position: relative; width: 36px; height: 36px; display: inline-block; }
.swatch input { position: absolute; inset: 0; opacity: 0; margin: 0; width: 100%; height: 100%; cursor: pointer; }
.swatch span { display: block; width: 36px; height: 36px; border-radius: 50%; background: var(--member); }
.swatch input:checked + span::after { content: ""; position: absolute; inset: -5px; border: 2px solid var(--text); border-radius: 50%; }
.swatch input:focus-visible + span { outline: 2px solid var(--text); outline-offset: 6px; }
.swatches-sm .swatch, .swatches-sm .swatch span { width: 36px; height: 36px; }

/* ---------- segmented choice chips (weekdays, kind, priority, split) ---------- */
.segmented, .weekday-picks { display: flex; gap: 6px; flex-wrap: wrap; }
.pick { position: relative; display: inline-block; }
.pick input { position: absolute; inset: 0; opacity: 0; margin: 0; width: 100%; height: 100%; cursor: pointer; }
.pick span { display: inline-flex; align-items: center; min-height: 40px; padding: 8px 14px; border-radius: var(--r-pill); border: 1px solid var(--border-strong); font-size: var(--fs-md); font-weight: 500; transition: background-color var(--dur-1) var(--ease), color var(--dur-1) var(--ease); }
.pick input:checked + span { background: var(--primary); color: var(--primary-text); border-color: var(--primary); }
.pick input:focus-visible + span { outline: 2px solid var(--text); outline-offset: 2px; }

/* ---------- inline editor (members, units) ---------- */
.row:has(> .editor) > .btn[disabled] { display: none; }
.editor { flex-basis: 100%; background: var(--surface-2); border-radius: var(--r-md); padding: var(--space-4); margin-top: var(--space-2); }
.editor-actions { display: flex; gap: var(--space-2); }
.editor-actions .btn-primary { flex: 1 1 auto; }
.editor-danger { display: flex; justify-content: flex-start; padding-top: var(--space-2); border-top: 1px solid var(--border); margin-top: var(--space-1); }

/* ---------- empty state ---------- */
.empty { text-align: center; padding: var(--space-6) var(--space-4); color: var(--text-muted); display: flex; flex-direction: column; gap: var(--space-3); align-items: center; }

/* ---------- tab bar ---------- */
.tabbar {
  position: relative; flex: 0 0 auto; width: 100%; z-index: 30; display: flex;
  height: calc(var(--tabbar-h) + var(--safe-bottom)); padding-bottom: var(--safe-bottom);
  border-top: 1px solid var(--border);
}
.tabbar.frost { background: var(--bg); -webkit-backdrop-filter: none; backdrop-filter: none; box-shadow: none; }
.tab { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; color: var(--text-muted); font-size: var(--fs-xs); position: relative; text-decoration: none; transition: color var(--dur-1) var(--ease); }
.tab:active { color: var(--text); }
.tab.is-active { color: var(--text); font-weight: 600; }
.tab.is-active svg { fill: currentColor; fill-opacity: 0.12; }
.tab.is-active::before { content: ""; position: absolute; top: -1px; left: 25%; right: 25%; height: 2px; background: var(--text); border-radius: 0 0 2px 2px; }
.tab-icon svg { width: 24px; height: 24px; }
/* Unread bubble on the Chat tab: the same FIXED notification red as the laundry "in use" dot
   (--notify), never the theme or the monochrome primary, so it reads as a signal not a style. */
:root { --notify: #dc2626; }
.tab-badge { position: absolute; top: 2px; left: calc(50% + 8px); min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--r-pill); background: var(--notify); color: #fff; font-size: var(--fs-xs); font-weight: 700; line-height: 18px; text-align: center; box-shadow: 0 0 0 2px var(--bg); font-variant-numeric: tabular-nums; }
.tab-badge:empty { display: none; }
@media (min-width: 900px) {
  body { padding-left: 96px; }
  body.auth { padding-left: 0; }
  body.landing { padding-left: 0; }
  body.legal:not([data-ws]) { padding-left: 0; }
  .tabbar { position: fixed; left: 0; top: 0; bottom: 0; right: auto; width: 96px; flex-direction: column; justify-content: flex-start; padding-top: var(--space-5); border-top: 0; border-right: 1px solid var(--border); height: auto; }
  .tab { flex: 0 0 72px; }
  .tab.is-active::before { top: 25%; bottom: 25%; left: -1px; right: auto; width: 2px; height: auto; border-radius: 0 2px 2px 0; }
}

/* ---------- htmx states ---------- */
.htmx-settling { animation: settle var(--dur-2) var(--ease); }
@keyframes settle { from { opacity: 0.4; } to { opacity: 1; } }

/* ---------- toasts ---------- */
.toasts { position: fixed; left: 50%; bottom: calc(var(--tabbar-h) + var(--safe-bottom) + 12px - var(--vp-gap)); transform: translateX(-50%); display: flex; flex-direction: column; gap: 6px; z-index: 40; pointer-events: none; max-width: calc(100vw - 32px); }
.toast { pointer-events: auto; display: inline-flex; align-items: center; gap: var(--space-3); background: var(--text); color: var(--bg); padding: 10px 16px; border-radius: var(--r-pill); font-size: var(--fs-md); box-shadow: var(--shadow-1); animation: toast-in 150ms var(--ease); cursor: pointer; }
.toast-text { flex: 1 1 auto; }
.toast-action { background: none; border: 0; padding: 0 4px; margin: -10px -4px -10px 0; min-height: 44px; color: inherit; font: inherit; font-weight: 700; text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
@keyframes toast-in { from { opacity: 0; transform: translateY(6px); } }
@media (min-width: 900px) { .toasts { bottom: 16px; left: calc(50% + 48px); } }

/* ---------- chat ---------- */
.channel-list .channel-row { color: var(--text); text-decoration: none; }
/* chat index: House · Groups · People, each its own card with a small header */
.chat-sections { display: flex; flex-direction: column; gap: var(--space-4); }
.chan-head { margin: 0 0 var(--space-1); font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-muted); font-weight: 700; }
.chan-head-row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); }
.chan-empty { margin: var(--space-2) 0 0; }
.badge-notify { background: var(--notify); color: #fff; }
html.themed .badge-notify { background: var(--notify); color: #fff; }
.channel-title { display: block; font-weight: 600; }
.channel-glyph { display: inline-flex; width: 36px; height: 36px; border-radius: var(--r-md); align-items: center; justify-content: center; background: var(--surface-2); color: var(--text-muted); font-weight: 700; flex: 0 0 auto; }
.channel-glyph--house { background: var(--primary); color: var(--primary-text); }
body.chat-page .page { padding-bottom: 0; }
.chat-thread { display: flex; flex-direction: column; flex: 1 0 auto; justify-content: flex-end; }
.messages:has(.msg) .empty { display: none; }
.messages { display: flex; flex-direction: column; gap: var(--space-2); padding-bottom: var(--space-3); }
.day-divider { text-align: center; color: var(--text-muted); font-size: var(--fs-xs); margin: var(--space-3) 0 var(--space-1); text-transform: uppercase; letter-spacing: 0.06em; }
.msg { display: flex; gap: var(--space-2); align-items: flex-end; max-width: 88%; position: relative; touch-action: pan-y; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; transition: transform var(--dur-2) var(--ease); }
.msg.is-swiping { transition: none; }
.msg.is-held .msg-bubble { transform: scale(1.03); }
.msg-stack { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.msg--mine .msg-stack { align-items: flex-end; }
.msg { -webkit-tap-highlight-color: transparent; }
/* Mouse users can still select text to copy; on touch a long press would start an iOS selection
   that spreads over the whole thread, so the thread is unselectable there and Copy lives in the
   long-press sheet. */
@media (hover: hover) and (pointer: fine) { .msg-body, .msg-reply { user-select: text; -webkit-user-select: text; } }
@media (hover: none) { .chat-thread, .chat-thread * { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; } }
/* Swipe-to-reply: the arrow sits behind the row and fades in as the bubble slides. */
.msg-swipe-hint { position: absolute; top: 50%; right: calc(100% + 4px); transform: translateY(-50%); opacity: 0; color: var(--text-muted); font-size: var(--fs-lg); pointer-events: none; transition: opacity var(--dur-1) var(--ease); }
.msg--mine .msg-swipe-hint { right: auto; left: calc(100% + 4px); }
.msg.is-swiping .msg-swipe-hint, .msg.is-armed .msg-swipe-hint { opacity: 1; }
.msg.is-armed .msg-swipe-hint { color: var(--text); }
/* Reactions under the bubble (fixed set, counts when >1, yours outlined). */
.msg-reactions { display: flex; flex-wrap: wrap; gap: 4px; padding: 0 2px; }
.reaction { display: inline-flex; align-items: center; gap: 3px; min-height: 26px; padding: 0 8px; border-radius: var(--r-pill); border: 1px solid var(--border); background: var(--surface); color: var(--text); font-size: var(--fs-sm); line-height: 1; cursor: pointer; }
.reaction.is-mine { border-color: var(--text); background: var(--surface-2); }
.reaction-count { font-weight: 600; font-variant-numeric: tabular-nums; }
/* Long-press sheet: OPAQUE, viewport-capped, never frosted (popover ruling 2026-09-24). */
.msg-sheet-scrim { position: fixed; inset: 0; z-index: 60; background: transparent; }
.msg-sheet { position: fixed; z-index: 61; width: max-content; min-width: 240px; max-width: min(calc(100vw - 2 * var(--space-4)), 360px); background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--r-lg); box-shadow: var(--shadow-2); padding: var(--space-2); display: flex; flex-direction: column; gap: 2px; }
@media (prefers-color-scheme: dark) { .msg-sheet { box-shadow: 0 8px 24px rgba(0, 0, 0, 0.6); } }
.msg-sheet-reactions { display: flex; justify-content: space-between; gap: 2px; padding: 2px 2px 6px; border-bottom: 1px solid var(--border); margin-bottom: 4px; }
.msg-sheet-emoji { width: 44px; height: 44px; border-radius: 50%; border: 1px solid transparent; background: none; font-size: 22px; line-height: 1; cursor: pointer; }
.msg-sheet-emoji:hover, .msg-sheet-emoji:focus-visible { background: var(--surface-2); }
.msg-sheet-emoji.is-mine { border-color: var(--text); background: var(--surface-2); }
.msg-sheet-item { min-height: 44px; text-align: left; padding: 0 var(--space-3); border: 0; border-radius: var(--r-md); background: none; color: var(--text); font-size: var(--fs-base); cursor: pointer; }
.msg-sheet-item:hover, .msg-sheet-item:focus-visible { background: var(--surface-2); }
.msg-sheet-danger { color: var(--danger); }
.msg-sheet-danger[hidden] { display: none; }
/* Who reacted (tap a chip, like an Instagram DM): same opaque sheet, one row per person. */
.msg-sheet-title { margin: 0; padding: 4px var(--space-3) 6px; font-size: var(--fs-xs); color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; }
.react-rows { display: flex; flex-direction: column; gap: 2px; max-height: 50vh; overflow-y: auto; }
.react-row { display: flex; align-items: center; gap: var(--space-3); width: 100%; min-height: 48px; padding: 4px var(--space-3); border: 0; border-radius: var(--r-md); background: none; color: var(--text); font: inherit; font-size: var(--fs-base); text-align: left; cursor: default; }
.react-row.is-mine { cursor: pointer; }
.react-row.is-mine:hover, .react-row.is-mine:focus-visible { background: var(--surface-2); }
.react-row-name { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; line-height: 1.2; }
.react-row-name small { color: var(--text-muted); font-size: var(--fs-xs); }
.react-row-emoji { font-size: 20px; line-height: 1; }
.msg--mine { align-self: flex-end; flex-direction: row-reverse; }
.msg--mine .avatar { display: none; }
.msg-bubble { background: var(--surface); border: 1px solid var(--border); border-radius: 16px 16px 16px 4px; padding: 8px 12px; min-width: 0; }
.msg--mine .msg-bubble { background: var(--primary); color: var(--primary-text); border-color: var(--primary); border-radius: 16px 16px 4px 16px; }
.msg-meta { font-size: var(--fs-xs); color: var(--text-muted); display: flex; gap: 6px; }
.msg--mine .msg-meta, .msg--mine .msg-reply, .msg--mine .msg-actions .link { color: color-mix(in srgb, var(--primary-text) 70%, transparent); }
.msg-author { font-weight: 600; color: var(--text); }
.msg--mine .msg-author { display: none; }
.msg-body { word-wrap: break-word; overflow-wrap: anywhere; white-space: pre-wrap; }
.msg-reply { font-size: var(--fs-sm); color: var(--text-muted); border-left: 3px solid var(--text-muted); padding-left: 8px; margin: 4px 0; }
.msg--mine .msg-reply { border-left-color: color-mix(in srgb, var(--primary-text) 50%, transparent); }
/* Hover / keyboard actions: collapsed (not display:none) so Tab can still reach the buttons, which
   then reveal the row via :focus-within. Touch users get the long-press sheet instead. */
.msg-actions { display: flex; gap: var(--space-3); font-size: var(--fs-sm); margin-top: 0; height: 0; overflow: hidden; opacity: 0; }
.msg:focus-within .msg-actions { height: auto; overflow: visible; opacity: 1; margin-top: 4px; }
@media (hover: hover) and (pointer: fine) {
  .msg:hover .msg-actions { height: auto; overflow: visible; opacity: 1; margin-top: 4px; }
}
.msg-actions .link { text-decoration: none; }
.msg-actions .link::before { content: ""; position: absolute; inset: -8px; }
.msg-actions .link { position: relative; }
.msg-delete { display: none; color: var(--danger); }
.msg--mine .msg-delete { color: color-mix(in srgb, var(--primary-text) 85%, transparent); }
.msg--mine .msg-delete, body[data-role="admin"] .msg-delete, body[data-role="owner"] .msg-delete { display: inline; }
.msg--deleted .msg-bubble { opacity: 0.7; }
.older-sentinel { text-align: center; padding: var(--space-2); }
.new-pill { position: fixed; left: 50%; transform: translateX(-50%); bottom: calc(var(--tabbar-h) + var(--safe-bottom) + 84px - var(--vp-gap)); z-index: 25; border-radius: var(--r-pill); padding: 8px 16px; background: var(--primary); color: var(--primary-text); border: 0; box-shadow: var(--shadow-1); font-weight: 600; cursor: pointer; }
.composer { position: sticky; bottom: 0; padding: var(--space-2) var(--space-4) var(--space-3); border-top: 1px solid var(--border); margin: 0 calc(-1 * var(--space-4)); z-index: 10; }
.composer-row { display: flex; gap: var(--space-2); align-items: flex-end; }
.composer textarea { resize: none; max-height: 120px; border-radius: var(--r-md); }
.reply-preview { font-size: var(--fs-sm); color: var(--text-muted); padding-bottom: 4px; display: flex; gap: var(--space-2); align-items: center; }
@media (min-width: 900px) { .composer { bottom: 0; } .new-pill { bottom: 100px; left: calc(50% + 48px); } }

/* ---------- lists ---------- */
.kind-glyph { display: inline-flex; width: 36px; height: 36px; border-radius: var(--r-md); align-items: center; justify-content: center; background: var(--surface-2); color: var(--text); flex: 0 0 auto; }
.kind-glyph svg { width: 20px; height: 20px; }
.items .item { align-items: flex-start; }
.check { width: 28px; height: 28px; border-radius: 50%; border: 2px solid var(--border-strong); background: transparent; flex: 0 0 auto; margin-top: 6px; cursor: pointer; position: relative; padding: 0; transition: border-color var(--dur-1) var(--ease), background-color var(--dur-1) var(--ease); }
.check::before { content: ""; position: absolute; inset: -8px; }
.check::after { content: ""; position: absolute; inset: 0; border-radius: 50%; opacity: 0; transition: opacity var(--dur-1); }
.check--done, .item--done .check { border-color: var(--primary); background: var(--primary); }
.check--done::after, .item--done .check::after {
  opacity: 1;
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><path d='M5 12l5 5 9-10'/></svg>") center / 16px no-repeat;
  mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><path d='M5 12l5 5 9-10'/></svg>") center / 16px no-repeat;
  background: var(--primary-text);
}
.inst--done .check--done { border-color: var(--ok); background: var(--ok); }
.inst--done .check--done::after { background: #fff; }
.check--skipped { border-color: var(--warn); background: var(--warn); }
.check--skipped::after {
  opacity: 1;
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round'><path d='M6 12h12'/></svg>") center / 16px no-repeat;
  mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round'><path d='M6 12h12'/></svg>") center / 16px no-repeat;
  background: #111;
}
.item--done .item-text { text-decoration: line-through; color: var(--text-muted); }
.item-text { cursor: pointer; display: flex; flex-direction: column; }
.item-note { display: block; }
.item--editing { border-top: 1px solid var(--border); }
.menu { position: relative; }
.menu summary { list-style: none; cursor: pointer; }
.menu summary::-webkit-details-marker { display: none; }
/* Popover menus are OPAQUE (frost made the page underneath bleed through and look like the
   card was pouring out); sized to the viewport so nothing escapes the screen. */
.menu-body {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 30;
  width: max-content; min-width: 220px; max-width: min(calc(100vw - 2 * var(--space-4)), 360px);
  background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--r-lg);
  padding: var(--space-3); display: flex; flex-direction: column; gap: var(--space-2);
  box-shadow: var(--shadow-2);
}
.menu-body.frost { background: var(--surface); -webkit-backdrop-filter: none; backdrop-filter: none; box-shadow: var(--shadow-2); }
@media (prefers-color-scheme: dark) { .menu-body { box-shadow: 0 8px 24px rgba(0, 0, 0, 0.6); } .menu-body.frost { box-shadow: 0 8px 24px rgba(0, 0, 0, 0.6); } }
.menu-body .row-form { flex-wrap: nowrap; }
.menu-body .row-form input { flex: 1 1 8rem; min-width: 0; }
.menu-body > * { min-width: 0; max-width: 100%; }


/* list kind glyphs as masks (no child markup, keeps the list-row test regex simple) */
.kind-glyph[class*="kind-"]:empty::before { content: ""; width: 20px; height: 20px; background: currentColor; }
.kind-glyph.kind-shopping:empty::before { -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='9' cy='20' r='1.5'/><circle cx='17' cy='20' r='1.5'/><path d='M3 4h2l2.4 10.5a1 1 0 0 0 1 .8h8.9a1 1 0 0 0 1-.8L20 8H6.5'/></svg>") center / 20px no-repeat; mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='9' cy='20' r='1.5'/><circle cx='17' cy='20' r='1.5'/><path d='M3 4h2l2.4 10.5a1 1 0 0 0 1 .8h8.9a1 1 0 0 0 1-.8L20 8H6.5'/></svg>") center / 20px no-repeat; }
.kind-glyph.kind-todo:empty::before { -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M5 12l4 4L19 6'/></svg>") center / 20px no-repeat; mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M5 12l4 4L19 6'/></svg>") center / 20px no-repeat; }
.kind-glyph.kind-custom:empty::before { -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M4 7h16M4 12h16M4 17h10'/></svg>") center / 20px no-repeat; mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M4 7h16M4 12h16M4 17h10'/></svg>") center / 20px no-repeat; }
.spinning svg, .spinning { animation: spin 600ms linear infinite; }

/* ---------- period nav (weeks, months) ---------- */
.period-nav, .week-nav { display: flex; align-items: center; gap: var(--space-1); margin-bottom: var(--space-3); }
.period-nav .btn, .week-nav .btn { min-width: 44px; min-height: 44px; padding: 0 var(--space-2); }
.period-nav .btn svg { width: 22px; height: 22px; }
.period-label, .week-label { flex: 1; text-align: center; font-weight: 700; }
.filter-row { display: flex; gap: var(--space-2); justify-content: flex-end; margin: calc(-1 * var(--space-2)) 0 var(--space-3); }

/* ---------- day agenda (chores + calendar) ---------- */
.day { display: flex; gap: var(--space-3); padding: var(--space-2) 0; }
.day + .day { border-top: 1px solid var(--border); }
.day-head { flex: 0 0 44px; display: flex; flex-direction: column; align-items: center; color: var(--text-muted); font-size: var(--fs-xs); padding-top: 6px; text-transform: uppercase; letter-spacing: 0.04em; }
.daynum, .day-num { font-size: var(--fs-lg); font-weight: 700; color: var(--text); width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-variant-numeric: tabular-nums; letter-spacing: 0; text-transform: none; }
.day--today .daynum, .day--today .day-num { background: var(--primary); color: var(--primary-text); }
.day-items { flex: 1; margin: 0; }
.day-empty { color: var(--text-muted); font-size: var(--fs-md); padding: 12px 0; min-height: 44px; display: flex; align-items: center; }
.day-empty a { color: var(--text-muted); }
.inst--done .inst-name, .inst--done .row-title { text-decoration: line-through; color: var(--text-muted); }
.inst--skipped .inst-name, .inst--skipped .row-title { font-style: italic; color: var(--text-muted); }
.inst--late .inst-name, .inst--late .row-title { color: var(--danger); }
.event-time { flex: 0 0 4.5em; font-variant-numeric: tabular-nums; color: var(--text-muted); font-size: var(--fs-md); line-height: 1.3; }

/* ---------- expenses ---------- */
.my-net { font-size: var(--fs-lg); }
.my-net.is-owed strong { color: var(--ok); }
.my-net.owes strong { color: var(--danger); }
.amount, .amount-pos, .amount-neg { font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums; text-align: right; min-width: 5.5em; }
.amount-pos { color: var(--ok); }
.amount-neg { color: var(--danger); }
.expense a, .settlement { color: var(--text); }
.settle-form { padding: var(--space-3) 0; border-top: 1px solid var(--border); }
.settle-form h3 { margin-bottom: var(--space-2); }
#split-hint { color: var(--text-muted); font-size: var(--fs-md); }
#split-hint.is-over { color: var(--danger); }
#split-hint.is-ok { color: var(--ok); }

/* ---------- calendar ---------- */
.flash-quiet { background: var(--warn-bg); color: var(--text); margin: 0 0 var(--space-2); border-left: 3px solid transparent; }
.flash-quiet.is-mine { border-left-color: var(--warn); }
.quiet-block { border-left: 3px solid var(--warn); padding-left: var(--space-2); background: var(--warn-bg); border-radius: 0 var(--r-sm) var(--r-sm) 0; }
.event a { color: var(--text); }

/* ---------- tickets ---------- */
.board { display: flex; flex-direction: column; gap: var(--space-3); }
.board-col { background: var(--surface-2); border-radius: var(--r-lg); padding: var(--space-3); display: flex; flex-direction: column; gap: var(--space-2); }
.board-head { font-size: var(--fs-md); margin: 0 0 var(--space-1); display: flex; justify-content: space-between; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-muted); }
.board-col:empty, .board-col .board-empty { color: var(--text-muted); font-size: var(--fs-md); padding: var(--space-1) 0; }
@media (min-width: 900px) {
  .board { flex-direction: row; align-items: flex-start; }
  .board-col { flex: 1 1 0; min-height: 120px; }
}
.tcard { display: flex; flex-direction: column; gap: 4px; background: var(--surface); border: 1px solid var(--border); border-left-width: 4px; border-radius: var(--r-md); padding: var(--space-2) var(--space-3); color: var(--text); text-decoration: none; transition: background-color var(--dur-1) var(--ease); }
.tcard:active { background: var(--surface-2); }
.tcard-title { font-weight: 600; }
.tcard-meta { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); font-size: var(--fs-md); color: var(--text-muted); }
.tcard-assignee { flex: 0 0 auto; }
.tcard.prio-high { border-left-color: var(--warn); }
.tcard.prio-urgent { border-left-color: var(--danger); }
.tcard.prio-low { border-left-color: var(--border-strong); }
.tcard.prio-normal { border-left-color: var(--text); }
.prio-tag { text-transform: uppercase; font-size: var(--fs-sm); font-weight: 600; letter-spacing: 0.04em; }
.prio-tag.prio-urgent { color: var(--danger); }
.prio-tag.prio-high { color: var(--warn); }
.ticket-status { display: flex; flex-direction: column; gap: var(--space-2); border-top: 1px solid var(--border); padding-top: var(--space-3); }
.ticket-done { display: flex; flex-direction: column; gap: var(--space-2); border-top: 1px solid var(--border); padding-top: var(--space-3); margin-top: var(--space-1); }
.ticket-done p { margin: 0; }
.status-pill { padding: 4px 12px; border-radius: var(--r-pill); background: var(--surface); border: 1px solid var(--border-strong); font-size: var(--fs-md); font-weight: 600; }
.status-assigned, .status-in_progress { background: var(--primary); color: var(--primary-text); border-color: var(--primary); }
.status-fixed, .status-closed { background: var(--ok-bg); color: var(--ok); border-color: transparent; }
.comment { align-items: flex-start; }
.comment-body { display: flex; flex-direction: column; gap: 2px; }
details.card summary { cursor: pointer; font-weight: 600; min-height: 44px; display: flex; align-items: center; }
details.card .tcard { margin-top: var(--space-2); }

/* ---------- home ---------- */
a.card.stat, .stat { display: flex; flex-direction: column; gap: 2px; color: var(--text); }
.stat .amount-pos, .stat .amount-neg { text-align: left; min-width: 0; }
.stat-label { font-size: var(--fs-md); color: var(--text-muted); }
.stat-value { font-size: var(--fs-2xl); font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
.activity .row { min-height: 40px; padding: 6px 0; }
.activity .row > .muted { white-space: nowrap; }


/* ---------- calendar views (day / week / month) ---------- */
.seg-links { display: inline-flex; border: 1px solid var(--border-strong); border-radius: var(--r-pill); padding: 2px; gap: 2px; }
.seg-links a { display: inline-flex; align-items: center; min-height: 34px; padding: 4px 14px; border-radius: var(--r-pill); text-decoration: none; color: var(--text-muted); font-weight: 600; font-size: var(--fs-md); transition: background-color var(--dur-1) var(--ease), color var(--dur-1) var(--ease); }
.seg-links a.is-on { background: var(--primary); color: var(--primary-text); }
.view-bar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); flex-wrap: wrap; margin-bottom: var(--space-3); }
.month { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.month-wd { text-align: center; font-size: var(--fs-xs); color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; padding: 4px 0 6px; }
.mcell { min-height: 64px; padding: 4px; border-top: 1px solid var(--border); text-decoration: none; color: var(--text); display: flex; flex-direction: column; gap: 4px; border-radius: var(--r-sm); transition: background-color var(--dur-1) var(--ease); }
.mcell:active, .mcell:hover { background: var(--surface-2); }
.mcell.is-out { opacity: 0.45; }
.mcell .daynum { width: 28px; height: 28px; font-size: var(--fs-md); }
.mcell.is-today .daynum { background: var(--primary); color: var(--primary-text); }
.mdots { display: flex; gap: 3px; flex-wrap: wrap; padding-left: 4px; }
.mdot { width: 7px; height: 7px; border-radius: 50%; background: var(--text); flex: 0 0 auto; }
.mdot.chore { background: transparent; box-shadow: inset 0 0 0 1.5px var(--text); }
.mdot.chore.late { box-shadow: inset 0 0 0 1.5px var(--danger); }
.mdot.quiet { background: var(--warn); }
.mmore { font-size: var(--fs-xs); color: var(--text-muted); padding-left: 4px; }
.mtitle { display: none; font-size: var(--fs-xs); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-left: 4px; }
.mtitle.chore { color: var(--text-muted); }
@media (min-width: 900px) {
  .mcell { min-height: 100px; }
  .mtitle { display: block; }
  .mdots { display: none; }
}
.day-title { font-weight: 700; font-size: var(--fs-lg); margin: 0 0 var(--space-2); }
.agenda-section { font-size: var(--fs-xs); color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; margin: var(--space-3) 0 var(--space-1); }
.mlegend { display: flex; gap: var(--space-3); font-size: var(--fs-xs); color: var(--text-muted); margin-top: var(--space-2); align-items: center; }
.mlegend span { display: inline-flex; align-items: center; gap: 4px; }

/* ---------- keyboard-aware chrome (iOS) ----------
   app-shell.js mirrors the on-screen keyboard height into --kb and toggles html.kb-open from
   the visualViewport. While the keyboard is up the tab bar slides away (it otherwise rides the
   layout viewport up and down as iOS scrolls the focused field into view) and the chat composer
   is lifted onto the visual viewport. */
html, body { overscroll-behavior-y: none; }
/* Open/close glide: app-shell applies the remembered keyboard height on focus and flags
   html.kb-anim for ~300 ms; the shell height and the tab bar collapse together on one curve, so
   the sticky composer rides up in one motion alongside the keyboard (no display:none jump). */
html.kb-anim body:not(.landing):not(.legal),
html.kb-anim .tabbar { transition: height 300ms cubic-bezier(0.2, 0.8, 0.2, 1), padding-bottom 300ms cubic-bezier(0.2, 0.8, 0.2, 1); }
.tabbar { overflow: hidden; }
html.kb-open .tabbar { height: 0; padding-bottom: 0; border-top-width: 0; }
/* iOS still panned the layout viewport to reveal the caret: move the shell down by the same
   amount so the header and composer stay exactly where they are on screen. */
html.kb-panned body:not(.landing):not(.legal) { transform: translateY(var(--vv-top, 0px)); }
html.kb-open .toasts { bottom: calc(var(--kb, 0px) + 12px); }
@media (min-width: 900px) { html.kb-open .tabbar { height: auto; padding-bottom: 0; border-top-width: 0; } }
.push-devices { margin-top: var(--space-2); }
.push-error { color: var(--danger); overflow-wrap: anywhere; }

/* ---------- settings accordion (More) ---------- */
.acc { border-top: 1px solid var(--border); }
.acc:first-child { border-top: 0; }
.acc > summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: var(--space-3); min-height: 52px; font-weight: 600; padding: var(--space-1) 0; }
.acc > summary::-webkit-details-marker { display: none; }
.acc > summary .kind-glyph { color: var(--text); }
.acc > summary::after { content: ""; margin-left: auto; width: 20px; height: 20px; flex: 0 0 auto; background: var(--text-muted); transition: transform var(--dur-2) var(--ease);
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M9 6l6 6-6 6'/></svg>") center / contain no-repeat;
  mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M9 6l6 6-6 6'/></svg>") center / contain no-repeat; }
.acc[open] > summary::after { transform: rotate(90deg); }
.acc-body { padding: 0 0 var(--space-3); }
/* Partials keep their own .card markup (htmx re-renders them); inside the accordion they are flat. */
.acc-body > .card { border: 0; padding: 0; border-radius: 0; background: transparent; }
.acc-body > .card > .card-head { display: none; }
@media (prefers-reduced-motion: reduce) { .acc > summary::after { transition: none; } }

/* ---------- reminders / preferences ---------- */
.pref-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: 10px 0; border-top: 1px solid var(--border); min-height: 48px; }
.pref-row:first-of-type { border-top: 0; }
.pref-label { display: flex; flex-direction: column; min-width: 0; }
.pref-label .row-sub { font-size: var(--fs-sm); }
.pref-row input[type=time], .pref-row select { width: auto; min-width: 7rem; max-width: 9rem; }
.pref-row input[type=checkbox] { width: 22px; height: 22px; margin: 0; }
.push-status { font-size: var(--fs-md); color: var(--text-muted); display: flex; gap: var(--space-2); align-items: center; }
.push-status::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--border-strong); flex: 0 0 auto; }
.push-status.is-on::before { background: var(--ok); }
.push-status.is-off::before { background: var(--warn); }

/* ---------- motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 1ms !important; animation-iteration-count: 1 !important; transition-duration: 1ms !important; }
  .btn:active { transform: none; }
  .htmx-request .btn[type=submit]::after, .btn.htmx-request::after { animation: none; border-right-color: currentColor; opacity: 0.5; }
}

/* ---------- calendar (agent) ---------- */
/* Day-number link inside a week row: keep the 40px circle tappable and unstyled as a link. */
a.daynum { text-decoration: none; }
a.daynum:hover, a.daynum:focus-visible { background: var(--surface-2); }
.day--today a.daynum:hover, .day--today a.daynum:focus-visible { background: var(--primary); }
/* Overdue chore title in a month cell. */
.mtitle.chore.late { color: var(--danger); }
/* Day view: sections stack inside one card; the first label sits flush under the nav. */
.day-title + .agenda-section { margin-top: 0; }
/* ---------- /calendar (agent) ---------- */

/* ---------- reminders (agent) ---------- */
.push-block { display: flex; flex-direction: column; gap: var(--space-2); padding-bottom: var(--space-3); border-bottom: 1px solid var(--border); margin-bottom: var(--space-2); }
.push-actions { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.push-actions .btn svg { width: 16px; height: 16px; margin-right: 4px; vertical-align: -3px; }
.push-note { margin: 0; }
.pref-controls { display: flex; align-items: center; gap: var(--space-2); flex: 0 0 auto; }
.push-test { display: flex; justify-content: flex-end; margin-top: var(--space-2); }

/* ---------- install prompt (banner at the top of signed-in pages + per-platform sheet) ---------- */
.install-banner {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; grid-template-areas: "icon copy close" ". actions .";
  column-gap: var(--space-3); row-gap: var(--space-2); align-items: start;
  padding: var(--space-3) var(--space-4); border: 1px solid var(--border-strong); border-radius: var(--r-lg); background: var(--surface-2);
}
.install-icon { grid-area: icon; width: 36px; height: 36px; display: inline-flex; align-items: center; justify-content: center; border-radius: var(--r-md); background: var(--primary); color: var(--primary-text); }
.install-icon svg { width: 20px; height: 20px; }
.install-copy { grid-area: copy; min-width: 0; padding-top: 2px; }
.install-actions { grid-area: actions; display: flex; gap: var(--space-2); flex-wrap: wrap; }
.install-banner > .btn-icon { grid-area: close; margin: -6px -10px 0 0; min-height: 40px; width: 40px; }
.install-banner .row-sub { font-size: var(--fs-sm); }
@media (display-mode: standalone), (display-mode: fullscreen) { .install-banner, [data-install-only] { display: none !important; } }

/* Bottom sheet on phones, centred card from 640px; OPAQUE like the popover menus. */
.sheet {
  position: fixed; inset: 0; width: 100%; max-width: 100%; height: fit-content; max-height: calc(100dvh - var(--space-6)); overflow-y: auto;
  margin: auto 0 0; padding: var(--space-4) var(--space-4) calc(var(--space-4) + var(--safe-bottom));
  border: 1px solid var(--border-strong); border-bottom: 0; border-radius: var(--r-lg) var(--r-lg) 0 0;
  background: var(--surface); color: var(--text); box-shadow: var(--shadow-2);
}
.sheet::backdrop { background: var(--scrim); }
.sheet-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-2); }
.sheet-head h2 { margin: 0; }
.sheet-head .btn-icon { margin-right: -10px; }
.sheet-lead { margin: 0 0 var(--space-3); }
.install-steps { margin: 0 0 var(--space-3); padding-left: 1.4rem; display: flex; flex-direction: column; gap: var(--space-2); }
.install-steps li { padding-left: 4px; }
.sheet-actions { display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-4); }
@media (min-width: 640px) {
  .sheet { margin: auto; max-width: 440px; border-bottom: 1px solid var(--border-strong); border-radius: var(--r-lg); padding-bottom: var(--space-4); }
}
@media (prefers-color-scheme: dark) { .sheet { box-shadow: 0 8px 24px rgba(0, 0, 0, 0.6); } }

/* ---------- per-user accent (Profile → App colour) ----------
   base.html sets --accent / --accent-text on <html class="themed">; everything below derives
   from those two so the same pick reads correctly in light and dark. Untinted default = the
   monochrome tokens above, byte for byte. --accent-ink is the accent pulled toward the page text
   for anything thin (links, active tab, focus ring) so a pale pick never disappears. */
:root { --accent-ink: var(--text); }
html.themed {
  --primary: var(--accent);
  --primary-text: var(--accent-text);
  --accent-ink: color-mix(in oklab, var(--accent) 72%, var(--text));
  --accent-soft: color-mix(in srgb, var(--accent) 10%, var(--surface));
  --surface-2: color-mix(in srgb, var(--accent) 8%, #f4f4f4);
  --border: color-mix(in srgb, var(--accent) 14%, #e3e3e3);
  --border-strong: color-mix(in srgb, var(--accent) 28%, #bdbdbd);
  --member: var(--accent);
}
@media (prefers-color-scheme: dark) {
  html.themed {
    --surface-2: color-mix(in srgb, var(--accent) 14%, #1c1c1c);
    --border: color-mix(in srgb, var(--accent) 18%, #2e2e2e);
    --border-strong: color-mix(in srgb, var(--accent) 32%, #4a4a4a);
  }
}
html.themed a { text-decoration-color: color-mix(in srgb, var(--accent-ink) 55%, transparent); }
html.themed :focus-visible { outline-color: var(--accent-ink); }
html.themed input:not([type=checkbox]):not([type=radio]):focus-visible, html.themed select:focus-visible, html.themed textarea:focus-visible { border-color: var(--accent-ink); }
html.themed input[type=checkbox], html.themed input[type=radio] { accent-color: var(--accent); }
html.themed #progress { background: var(--accent); }
html.themed .tab.is-active { color: var(--accent-ink); }
html.themed .tab.is-active::before { background: var(--accent); }
html.themed .tab:active { color: var(--accent-ink); }
html.themed .topbar-title { color: var(--accent-ink); }
html.themed .card-head h2 { color: var(--accent-ink); }
html.themed .chip { background: var(--accent-soft); }
html.themed .editor { background: var(--accent-soft); }
html.themed .toast { background: var(--accent); color: var(--accent-text); }
html.themed .toast-action { color: inherit; }
html.themed .btn-primary:focus-visible { outline-color: var(--accent-text); }
html.themed .swatch input:checked + span::after, html.themed .swatch input:focus-visible + span, html.themed .pick input:focus-visible + span { border-color: var(--accent-ink); outline-color: var(--accent-ink); }
html.themed .install-banner { background: var(--accent-soft); }

/* the picker itself */
.accent-field .hint { margin: 0 0 var(--space-2); }
.accent-row { display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap; }
.accent-wheel { position: relative; width: 56px; height: 56px; flex: 0 0 auto; cursor: pointer; }
.accent-wheel input[type=color] { position: absolute; inset: 0; width: 100%; height: 100%; padding: 0; margin: 0; border: 0; border-radius: 50%; background: none; cursor: pointer; -webkit-appearance: none; appearance: none; min-height: 0; }
.accent-wheel input[type=color]::-webkit-color-swatch-wrapper { padding: 0; }
.accent-wheel input[type=color]::-webkit-color-swatch { border: 0; border-radius: 50%; }
.accent-wheel input[type=color]::-moz-color-swatch { border: 0; border-radius: 50%; }
.accent-wheel-ring { position: absolute; inset: -4px; border-radius: 50%; border: 2px solid var(--border-strong); pointer-events: none;
  background: conic-gradient(#f00, #ff0, #0f0, #0ff, #00f, #f0f, #f00); -webkit-mask: radial-gradient(circle, transparent 60%, #000 61%); mask: radial-gradient(circle, transparent 60%, #000 61%); border: 0; }
.accent-wheel input[type=color]:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 6px; }
.accent-presets { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.accent-preset { width: 32px; height: 32px; border-radius: 50%; border: 0; padding: 0; background: var(--swatch); cursor: pointer; position: relative; }
.accent-preset[aria-pressed="true"]::after { content: ""; position: absolute; inset: -5px; border: 2px solid var(--text); border-radius: 50%; }
.accent-preset:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 4px; }

/* payment handles (More → Your profile; Expenses → Settle up → Pay) */
.pay-methods { margin-top: var(--space-3); }
.pay-handle { font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.pay-sheet { margin: var(--space-2) 0 var(--space-3); }
.pay-sheet .card-head h3 { margin: 0; }
.pay-methods .field .hint { margin-left: var(--space-1); color: var(--text-muted); font-weight: 400; }

/* ---------- invite code typing + join page ---------- */
.code-input { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: 0.12em; text-transform: uppercase; font-size: var(--fs-lg); }
.invite-code-sm { font-size: var(--fs-base); letter-spacing: 0.08em; }

/* ---------- laundry ---------- */
.laundry-board { display: flex; flex-direction: column; gap: var(--space-4); }
.machine { border-left-width: 4px; border-left-color: var(--border-strong); }
.machine--free { border-left-color: var(--ok); }
.machine--done { border-left-color: var(--warn); }
.machine--focus { box-shadow: var(--shadow-1); }
.machine-head { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-3); }
.machine-name { margin: 0; font-size: var(--fs-xl); }
.machine-pill { flex: 0 0 auto; padding: 4px 10px; border-radius: var(--r-pill); font-size: var(--fs-sm); font-weight: 600; border: 1px solid var(--border-strong); white-space: nowrap; }
.machine-pill--free { border-color: var(--ok); color: var(--ok); }
.machine-pill--running { background: var(--primary); color: var(--primary-text); border-color: var(--primary); }
.machine-pill--done { border-color: var(--warn); color: var(--warn); }
.machine-status { font-size: var(--fs-lg); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.countdown { font-variant-numeric: tabular-nums; font-weight: 700; }
.machine-start-row { display: flex; align-items: flex-end; gap: var(--space-3); }
.machine-start-row .field { flex: 1 1 auto; }
.machine-start-row .row-form { flex-wrap: nowrap; }
.machine-start-row input[type=number] { max-width: 6.5rem; }
.machine-go { flex: 0 0 auto; min-height: 48px; padding: 0 var(--space-5); }
.machine-note summary { cursor: pointer; list-style: none; }
.machine-note summary::-webkit-details-marker { display: none; }
.machine-note input { margin-top: var(--space-2); }
.machine-waiting { margin: var(--space-2) 0 0; }
.tag-panel { padding: var(--space-3); background: var(--surface-2); border-radius: var(--r-md); margin-bottom: var(--space-3); }
.tag-panel h3 { margin-bottom: var(--space-1); }
.tag-url { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: var(--fs-md); overflow-wrap: anywhere; margin: 0 0 var(--space-2); }
.machine-acc summary { display: flex; align-items: center; gap: var(--space-3); min-height: 48px; cursor: pointer; list-style: none; padding: var(--space-2) 0; }
.machine-acc summary::-webkit-details-marker { display: none; }
.machine-row { border-top: 1px solid var(--border); }
.machine-row:first-child { border-top: 0; }
.how-list { margin: 0 0 var(--space-3); padding-left: 1.25em; }
.how-list li { margin-bottom: var(--space-2); }
.stat-of { font-size: var(--fs-md); color: var(--text-muted); font-weight: 500; }

/* ---------- home widgets ---------- */
.widgets { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }
.widgets > * { min-width: 0; }
@media (min-width: 640px) { .widgets { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.stat-value-sm { font-size: var(--fs-lg); }
.stat .muted.small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Laundry widget: availability colours are FIXED (green free / red in use / yellow done) — they
   carry meaning and never follow the per-user app colour or the monochrome palette. */
.laundry-widget { --lw-free: #16a34a; --lw-busy: var(--notify); --lw-done: #eab308; text-decoration: none; color: var(--text); display: block; }
.laundry-widget .card-head { margin-bottom: var(--space-2); }
.lw-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.lw-row { display: flex; align-items: center; gap: var(--space-3); min-height: 40px; padding: 4px 0; border-top: 1px solid var(--border); }
.lw-row:first-child { border-top: 0; }
.lw-dot { width: 12px; height: 12px; border-radius: 50%; flex: 0 0 auto; background: var(--lw-busy); box-shadow: 0 0 0 3px color-mix(in srgb, var(--lw-busy) 22%, transparent); }
.lw-free .lw-dot { background: var(--lw-free); box-shadow: 0 0 0 3px color-mix(in srgb, var(--lw-free) 22%, transparent); }
.lw-done .lw-dot { background: var(--lw-done); box-shadow: 0 0 0 3px color-mix(in srgb, var(--lw-done) 28%, transparent); }
.lw-name { font-weight: 600; flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lw-state { color: var(--text-muted); font-size: var(--fs-md); white-space: nowrap; font-variant-numeric: tabular-nums; }
.lw-free .lw-state { color: var(--lw-free); font-weight: 600; }
.lw-mine .lw-state { color: var(--text); font-weight: 600; }
html.themed .laundry-widget .card-head h2 { color: var(--text); }

/* ---------- printable machine labels ---------- */
.labels { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-4); }
.label { border: 2px solid #000; border-radius: 10px; padding: 14px 12px; background: #fff; color: #000; text-align: center; break-inside: avoid; display: flex; flex-direction: column; align-items: center; gap: 6px; }
.label-name { font-size: 2.4rem; font-weight: 800; letter-spacing: -0.02em; line-height: 1; }
.label-sub { font-size: 0.85rem; color: #333; }
.label-qr { width: 150px; padding: 6px; background: #fff; }
.label-qr svg { display: block; width: 100%; height: auto; }
.label-qr svg path { fill: #000; }
.label-foot { font-size: 0.72rem; color: #333; }
.tag-host { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
@media print {
  .topbar, .tabbar, .install-banner, .no-print, #toasts, #progress { display: none !important; }
  body, body:not(.landing):not(.legal) { display: block; height: auto; padding: 0; background: #fff; }
  body:not(.landing):not(.legal) > .page { overflow: visible; padding: 0; }
  .labels { grid-template-columns: repeat(2, 1fr); gap: 10mm; }
  .label { border-color: #000; }
}

/* select arrow (appearance:none above removed the native one); last so no shorthand `background` beats it */
select { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M7 10l5 5 5-5'/></svg>"); background-repeat: no-repeat; background-position: right 10px center; background-size: 18px; padding-right: 34px; }

/* Plan banner (billing, 2026-10-11): trial countdown / read-only notice above the page. */
.plan-banner { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; justify-content: space-between;
  margin: 0 0 var(--space-3); padding: var(--space-2) var(--space-3); border-radius: var(--r-md);
  border: 1px solid var(--border); background: var(--surface); font-size: var(--fs-sm); }
.plan-banner.locked { border-color: var(--danger, #b42318); }
.plan-banner a { font-weight: 700; }
.legal-banner span a { font-weight: inherit; text-decoration: underline; }
.legal-banner form { margin: 0; }

/* Home tools (solo features, 2026-10-14): photos, staples, agreement text. */
.prose { margin-top: var(--space-2); line-height: 1.55; overflow-wrap: anywhere; }
.right { text-align: right; }
form.inline { display: inline; }
.photo-strip { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: var(--space-2); margin: var(--space-2) 0; }
.photo-strip:empty { display: none; }
.photo { margin: 0; display: flex; flex-direction: column; gap: 2px; }
.photo img { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: var(--r-md); border: 1px solid var(--border); background: var(--surface-2); display: block; }
.photo figcaption { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; line-height: 1.3; }
.photo figcaption .btn { padding: 0; min-height: 0; height: auto; }
.photo-add { margin-top: var(--space-2); }
.photo-add label.btn { cursor: pointer; }
.staples { margin-bottom: var(--space-3); }
.chip-row { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-1); }
.chip-btn { border: 1px solid var(--border); color: var(--text); cursor: pointer; font: inherit; }
.chip-btn::before { display: none; }
