/* FamleeTime design system.
   Style guide (design/project/FamleeTime Wireframes.dc.html, turn 0):
   soft & tactile — rounded cards, gentle shadows; green accent on a warm
   brown ground (roots and trees); cream cards float on the brown so the
   reading surface is always the brightest thing on screen. Headline serif
   (Newsreader) for names and dates, plain sans (Public Sans) for everything
   functional. Multi-generational audience: 17px body (>=16 min), 44px min
   tap target, every control carries a text label, one primary action per
   screen and it is always green and always the largest. */

:root {
  color-scheme: light;

  /* ground = the warm parchment the whole app sits on; surfaces float above
     it. It used to be a dark brown (#6b5443) — headings, back-links and list
     rows that render straight on the ground (outside a .card) were then
     near-black ink on brown, ~2.3:1 and unreadable. The brown identity now
     lives only on the dark header bar (--ground-deep). */
  --ground: #ece3d3;
  --ground-deep: #4a3a2c;
  --on-ground: #f4ede3;
  --on-ground-soft: #d9ccbb;

  --surface: #fffdf8;
  --surface-sunken: #f2ead9;
  --tint: #e4ede6; /* soft green — selected states, avatar fallbacks */
  --tint-border: #c7dccc;

  --accent: #3f6b54;
  --accent-strong: #2e5040;

  --ink: #2b2019;
  --ink-soft: #5b5145;

  --border: #e0d5bf;
  --border-strong: #c9baa0;

  --danger: #a5372b;

  --radius: 14px;
  --radius-sm: 10px;
  --radius-pill: 999px;

  --shadow: 0 2px 8px rgba(36, 28, 22, 0.12), 0 1px 2px rgba(36, 28, 22, 0.08);
  --shadow-lift: 0 12px 34px rgba(36, 28, 22, 0.2);

  --font-body: "Public Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-head: "Newsreader", Georgia, "Times New Roman", serif;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.6;
  background: var(--ground);
  color: var(--ink);
}

h1,
h2,
h3,
h4 {
  font-family: var(--font-head);
  font-weight: 600;
  line-height: 1.2;
  color: var(--ink);
  margin: 0 0 0.6rem;
}

h1 {
  font-size: 1.9rem;
}
h2 {
  font-size: 1.3rem;
}

a {
  color: var(--accent-strong);
}
a:hover {
  color: var(--accent);
}

/* ---------- layout ---------- */

.container {
  max-width: 680px;
  margin: 0 auto;
  padding: 2rem 1.25rem 4rem;
}

.container-wide {
  max-width: 1200px;
  margin: 0 auto;
  padding: 1.5rem 1.5rem 4rem;
}

.stack {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.stack-sm {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.section-label {
  font-size: 0.72rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--ink-soft);
}

.muted {
  color: var(--ink-soft);
  font-size: 0.95rem;
}

/* ---------- top bar (design 1a: avatar top-left routes to own profile) ---------- */

.site-header {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.7rem 1.25rem;
  background: var(--ground-deep);
  border-bottom: 1px solid rgba(0, 0, 0, 0.25);
  position: sticky;
  top: 0;
  z-index: 30;
}

.site-avatar {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  background: var(--tint);
  color: var(--accent-strong);
  font-weight: 700;
  font-size: 1.05rem;
  text-decoration: none;
  border: 2px solid rgba(255, 255, 255, 0.25);
  object-fit: cover;
}
.site-avatar:hover {
  border-color: rgba(255, 255, 255, 0.6);
}

.brand {
  font-family: var(--font-head);
  font-size: 1.35rem;
  font-weight: 600;
  color: var(--on-ground);
  text-decoration: none;
}

.site-username {
  color: var(--on-ground-soft);
  font-weight: 600;
  font-size: 0.95rem;
  text-decoration: none;
}
.site-username:hover {
  color: var(--on-ground);
}

/* Header search box: fetches the caller's whole (small) roster once on
   focus and filters it client-side — see app/static/js/search.js. */
.site-search {
  position: relative;
  flex: 0 1 240px;
  min-width: 0;
}
.site-search-input {
  min-height: 40px;
  padding: 0.5rem 0.9rem;
  border-radius: var(--radius-pill);
  border: 1px solid rgba(255, 255, 255, 0.3);
  background: rgba(255, 255, 255, 0.12);
  color: var(--on-ground);
}
.site-search-input::placeholder {
  color: var(--on-ground-soft);
}
.site-search-input:focus {
  background: var(--surface);
  color: var(--ink);
}
.site-search-results {
  position: absolute;
  z-index: 40;
  top: calc(100% + 0.4rem);
  left: 0;
  right: 0;
  margin: 0;
  padding: 0.35rem;
  list-style: none;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lift);
  max-height: 60vh;
  overflow-y: auto;
}
.site-search-result {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.5rem 0.6rem;
  border-radius: var(--radius-sm);
  color: var(--ink);
  text-decoration: none;
  font-weight: 600;
}
.site-search-result:hover,
.site-search-result.is-active {
  background: var(--tint);
}
.site-search-result-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  flex: none;
  background: var(--tint);
  color: var(--accent-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.85rem;
  overflow: hidden;
}
.site-search-result-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.site-search-empty {
  padding: 0.5rem 0.6rem;
  color: var(--ink-soft);
  font-size: 0.9rem;
}

.site-nav {
  margin-left: auto;
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  row-gap: 0.3rem;
  align-items: center;
}
.site-nav a {
  color: var(--on-ground);
  text-decoration: none;
  font-weight: 600;
  font-size: 1rem;
  padding: 0.6rem 0.95rem;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  border-radius: var(--radius-pill);
}
.site-nav a:hover {
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
}
.site-nav a.is-active {
  background: var(--accent);
  color: #fff;
}

.btn-quiet {
  background: transparent;
  color: var(--on-ground);
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: var(--radius-pill);
  padding: 0.55rem 0.9rem;
  min-height: 44px;
  font: 600 1rem var(--font-body);
  cursor: pointer;
}
.btn-quiet:hover {
  background: rgba(255, 255, 255, 0.12);
}

/* Wrapper around username + nav + Log out. On desktop it is transparent
   (display: contents) so those three flow in the header row exactly as
   before; on a phone it becomes the collapsible drawer. */
.site-menu {
  display: contents;
}

/* The "Menu" button that opens the drawer. Hidden on desktop, and hidden
   entirely without JS (it would be a dead control) — the no-JS phone
   fallback just stacks the menu open. */
.nav-toggle {
  display: none;
  margin-left: auto;
  align-items: center;
  gap: 0.5rem;
  background: transparent;
  color: var(--on-ground);
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: var(--radius-pill);
  padding: 0.55rem 0.9rem;
  min-height: 44px;
  font: 600 1rem var(--font-body);
  cursor: pointer;
}
.nav-toggle:hover {
  background: rgba(255, 255, 255, 0.12);
}
.nav-toggle::before {
  content: "";
  width: 18px;
  height: 2px;
  background: currentColor;
  box-shadow: 0 -6px 0 currentColor, 0 6px 0 currentColor;
}

/* Desktop only: search sits after the user's name instead of before it
   (avatar · brand · name · search · nav · Log out). `.site-menu`'s
   display:contents flattens name/nav/Log out into this same flex row, so
   reordering them here is enough — the mobile drawer below has its own
   layout and is untouched. */
@media (min-width: 861px) {
  .site-username {
    order: 1;
  }
  .site-search {
    order: 2;
  }
  .site-nav {
    order: 3;
  }
  #logout-button {
    order: 4;
  }
}

/* The full row (avatar · brand · name · four nav links · Log out) stops
   fitting comfortably well before phone widths, so the drawer takes over at
   a tablet-ish width, not just at 640. */
@media (max-width: 860px) {
  .site-header {
    flex-wrap: wrap;
    row-gap: 0.5rem;
  }
  html.js .nav-toggle {
    display: inline-flex;
  }
  .site-search {
    order: 2;
    flex: 1 1 100%;
    max-width: none;
  }
  .site-menu {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0.2rem;
    width: 100%;
    order: 3;
  }
  .site-username {
    padding: 0.5rem 0.25rem;
  }
  .site-nav {
    flex-direction: column;
    align-items: stretch;
    gap: 0.15rem;
    margin-left: 0;
  }
  .site-nav a {
    padding: 0.75rem;
  }
  #logout-button {
    align-self: flex-start;
    margin-top: 0.35rem;
  }
  /* JS present: drawer stays closed until the Menu button toggles it. */
  html.js .site-menu {
    display: none;
  }
  html.js .site-menu.is-open {
    display: flex;
  }
}

@media (max-width: 640px) {
  /* give content back the side margin the header row eats */
  .container {
    padding: 1.5rem 1rem 3rem;
  }
  .container-wide {
    padding: 1rem 1rem 3rem;
  }
  h1 {
    font-size: 1.55rem;
  }
  h2 {
    font-size: 1.2rem;
  }
  /* three across is the most that stays tappable on a phone */
  .my-photos-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* ---------- cards ---------- */

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.25rem;
}

/* ---------- tables ---------- */

/* Wrap any wide table in <div class="table-scroll"> so it scrolls inside its
   own box on a phone instead of pushing the whole page sideways. */
.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
.table-scroll table {
  border-collapse: collapse;
  width: 100%;
  min-width: 640px;
}
.table-scroll th,
.table-scroll td {
  text-align: left;
  padding: 0.6rem 0.85rem;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
.table-scroll th {
  font-family: var(--font-head);
  font-weight: 600;
  white-space: nowrap;
}
.table-scroll tbody tr:last-child th,
.table-scroll tbody tr:last-child td {
  border-bottom: 0;
}

/* ---------- buttons (legacy .button/.button.secondary kept working) ---------- */

.btn,
.button,
button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  min-height: 44px;
  padding: 0.6rem 1.15rem;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  background: var(--accent);
  color: #fff;
  font: 600 1rem/1 var(--font-body);
  text-decoration: none;
  cursor: pointer;
}
.btn:hover,
.button:hover,
button:hover {
  background: var(--accent-strong);
  color: #fff;
}

.btn-secondary,
.button.secondary {
  background: transparent;
  color: var(--accent-strong);
  border-color: var(--accent);
}
.btn-secondary:hover,
.button.secondary:hover {
  background: var(--tint);
  color: var(--accent-strong);
}

.btn-danger,
.button.danger {
  background: var(--danger);
}
.btn-danger:hover,
.button.danger:hover {
  background: #8f2f25;
}

/* the one primary action per screen — always the largest control */
.btn-lg {
  min-height: 52px;
  padding: 0.85rem 1.6rem;
  font-size: 1.08rem;
}
.btn-block {
  width: 100%;
}

/* .btn-quiet is defined in the top-bar block above and reused elsewhere */

/* ---------- forms ---------- */

form {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  max-width: 440px;
}
/* The `hidden` attribute must win over element display rules below
   (e.g. `label { display: flex }`), so JS toggling `el.hidden` actually
   hides the element. */
[hidden] {
  display: none !important;
}
label {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  font-size: 0.95rem;
  font-weight: 600;
}
input,
textarea,
select {
  width: 100%;
  min-height: 44px;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  font: 1rem var(--font-body);
  font-family: inherit;
  background: var(--surface);
  color: var(--ink);
}
input:focus,
textarea:focus,
select:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: var(--accent);
}
textarea {
  min-height: 96px;
  resize: vertical;
}
fieldset {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 1rem;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
legend {
  padding: 0 0.4rem;
  font-size: 0.9rem;
  color: var(--ink-soft);
  font-weight: 600;
}

/* ---------- notices, badges, misc ---------- */

.error {
  color: var(--danger);
}
.notice {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 4px solid var(--ink-soft);
  border-radius: var(--radius-sm);
  padding: 1rem 1.15rem;
  margin: 1rem 0;
}
.notice p {
  margin: 0.25rem 0;
}
.notice-error {
  border-left-color: var(--danger);
  background: color-mix(in srgb, var(--danger) 6%, var(--surface));
}

.badge {
  display: inline-block;
  padding: 0.15rem 0.6rem;
  border-radius: var(--radius-pill);
  background: var(--tint);
  color: var(--accent-strong);
  font-size: 0.8rem;
  font-weight: 700;
  margin-left: 0.4rem;
}

/* ---------- calendar connection strip (_calendar_connection.html) ---------- */
/* The not-connected / reconnect states reuse .notice + .button; only the
   connected state — a quiet status line above a Manage / Disconnect row —
   needs its own layout. */
.calendar-conn {
  margin-top: 1rem;
}
.calendar-conn-status {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.95rem;
}
.calendar-conn-check {
  flex: none;
  color: var(--accent);
}
.calendar-conn-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.6rem;
}
.calendar-conn-actions form {
  margin: 0;
}

ul {
  list-style: none;
  padding: 0;
  margin: 0;
}
li {
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--border);
}
/* opt-out for templates that lay lists out themselves */
.plain-list li {
  padding: 0;
  border: 0;
}
section {
  margin-bottom: 2rem;
}

.avatar {
  display: block;
  width: 120px;
  height: 120px;
  object-fit: cover;
  border-radius: 16px;
  margin-bottom: 0.75rem;
  border: 1px solid var(--border);
}
.avatar-sm {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  margin: 0;
  flex-shrink: 0;
}

/* generic circular avatar with an initials fallback */
.mini-avatar {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--tint);
  color: var(--accent-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  flex: none;
  text-transform: uppercase;
}

/* ================================================================
   Feed (design 1a)
   ================================================================ */

.feed-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 310px;
  gap: 1.5rem;
  align-items: start;
}
@media (max-width: 940px) {
  .feed-layout {
    grid-template-columns: 1fr;
  }
}

.feed-main {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.feed-rail {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  position: sticky;
  top: 76px;
}
@media (max-width: 940px) {
  .feed-rail {
    position: static;
  }
}

.rail-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1rem 1.1rem;
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
}

.family-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.7rem 0.5rem;
}
.family-grid a {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  text-decoration: none;
  color: var(--ink);
}
.family-grid .mini-avatar {
  width: 54px;
  height: 54px;
}
.family-grid-name {
  font-size: 0.78rem;
  text-align: center;
  line-height: 1.15;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  width: 62px;
}

.coming-up-item {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--border);
}
.coming-up-item:last-of-type {
  border-bottom: 0;
}
.coming-up-when {
  font-family: var(--font-head);
  font-weight: 600;
  color: var(--accent-strong);
  font-size: 0.95rem;
}
.coming-up-what {
  font-size: 0.92rem;
}

/* composer */
.composer {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.15rem 1.25rem;
  display: flex;
  gap: 0.85rem;
  align-items: flex-start;
  margin: 0;
}
.composer-form {
  flex: 1;
  max-width: none;
  gap: 0.75rem;
}
.composer-types {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.composer-types button {
  flex: 1;
  min-width: 90px;
  background: var(--surface-sunken);
  color: var(--accent-strong);
  border: 1px solid var(--border-strong);
}
.composer-types button:hover {
  background: var(--tint);
}
/* Pictures field flagged when arriving via /feed?compose=photos ("Post more?"). */
.composer-form label.is-target {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
  border-radius: 4px;
}

/* post cards — one shell, a small kind label per type (design 1a) */
.post-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.15rem 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.post-card-header {
  display: flex;
  gap: 0.7rem;
  align-items: center;
}
.post-card-header .mini-avatar {
  width: 44px;
  height: 44px;
}
.post-author {
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 1.05rem;
  color: var(--ink);
  text-decoration: none;
}
.post-author:hover {
  text-decoration: underline;
}
.post-card-time {
  font-size: 0.85rem;
  color: var(--ink-soft);
}
.post-kind {
  margin-left: auto;
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--ink-soft);
  background: var(--surface-sunken);
  border-radius: var(--radius-pill);
  padding: 0.2rem 0.6rem;
}
.post-card-text {
  white-space: pre-wrap;
  margin: 0;
  font-size: 1.02rem;
}
.post-headline {
  font-family: var(--font-head);
  font-size: 1.25rem;
  font-weight: 600;
  margin: 0;
}
.post-pictures {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.post-pictures img {
  width: 100%;
  max-width: 360px;
  max-height: 340px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
}
.post-pictures.multi img {
  width: 160px;
  height: 160px;
}
.post-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.post-actions .btn-secondary {
  padding: 0.5rem 0.9rem;
}
.post-card.is-milestone {
  background: var(--tint);
  border-color: var(--tint-border);
}
.post-card.is-recipe {
  flex-direction: row;
  align-items: flex-start;
  gap: 1rem;
}
.post-card.is-recipe .recipe-thumb {
  width: 110px;
  height: 92px;
  border-radius: var(--radius-sm);
  object-fit: cover;
  background: var(--surface-sunken);
  flex: none;
}

/* ================================================================
   Profile view (design 1c)
   ================================================================ */

.profile-cover {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 1;
  object-fit: cover;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: linear-gradient(120deg, var(--tint), var(--surface-sunken));
}

.profile-head {
  display: flex;
  align-items: flex-end;
  gap: 1.25rem;
  margin-top: -60px;
  padding: 0 1.25rem;
}
.profile-avatar {
  width: 128px;
  height: 128px;
  border-radius: 50%;
  border: 5px solid var(--surface);
  background: var(--surface);
  object-fit: cover;
  flex: none;
  box-shadow: var(--shadow);
}
.profile-identity {
  flex: 1;
  padding-bottom: 0.4rem;
}
.profile-identity h1 {
  margin: 0;
}
.profile-nickname {
  color: var(--ink-soft);
  font-size: 1rem;
}
.profile-head .btn {
  align-self: flex-end;
  margin-bottom: 0.4rem;
}

.profile-cols {
  display: grid;
  grid-template-columns: 1.5fr 1fr;
  gap: 1.5rem;
  margin-top: 1.5rem;
  align-items: start;
}
@media (max-width: 860px) {
  .profile-head {
    flex-wrap: wrap;
    margin-top: -48px;
  }
  .profile-head .btn {
    align-self: flex-start;
    margin-bottom: 0;
  }
  .profile-cols {
    grid-template-columns: 1fr;
  }
}

.pcol {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}
.pcard {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.15rem 1.25rem;
}
.pcard h2 {
  font-size: 1.15rem;
  margin: 0 0 0.7rem;
}
.pcard p {
  margin: 0;
}

.pin-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.5rem;
}
.pin-grid img,
.pin-grid .pin {
  aspect-ratio: 1;
  width: 100%;
  border-radius: var(--radius-sm);
  object-fit: cover;
  background: var(--surface-sunken);
}

.timeline {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  max-height: 340px;
  overflow-y: auto;
  margin: 0;
  padding: 0;
  list-style: none;
}
.timeline li {
  display: flex;
  gap: 0.85rem;
  padding: 0;
  border: 0;
}
.timeline .year {
  font-family: var(--font-head);
  font-weight: 600;
  color: var(--accent-strong);
  flex: none;
  width: 3.4rem;
}

.kv-row {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.45rem 0;
  border-bottom: 1px solid var(--border);
}
.kv-row:last-child {
  border-bottom: 0;
}
.kv-row dt {
  color: var(--ink-soft);
  font-size: 0.9rem;
}
.kv-row dd {
  margin: 0;
  text-align: right;
  font-weight: 600;
}

.your-posts-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 0.5rem;
}
.your-posts-grid .mini-post {
  background: var(--surface-sunken);
  border-radius: var(--radius-sm);
  padding: 0.6rem 0.7rem;
  font-size: 0.85rem;
  border: 1px solid var(--border);
}
.your-posts-grid img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: var(--radius-sm);
}

.feed-sentinel {
  text-align: center;
  padding: 1rem;
}

/* ================================================================
   Profiles — Phase 2 (recipes, pinned/my photos, life timeline,
   photo viewer)
   ================================================================ */

.pcard-subhead {
  font-size: 1rem;
  margin: 1.1rem 0 0.6rem;
}

/* Shared "action already taken" state for Remember it / Pin */
.is-done {
  opacity: 0.75;
  cursor: default;
}

/* Per-picture pin control on feed post images */
.post-pictures .post-picture {
  position: relative;
  display: flex;
}
.post-pictures .post-picture img {
  display: block;
  width: 100%;
  max-width: 360px;
  max-height: 340px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  cursor: zoom-in;
}
.post-pictures.multi .post-picture img {
  width: 160px;
  height: 160px;
}
.pin-btn-form {
  position: absolute;
  top: 0.4rem;
  right: 0.4rem;
  margin: 0;
  max-width: none;
}
.pin-btn {
  font-size: 0.75rem;
  padding: 0.15rem 0.55rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.12s;
}
.post-picture:hover .pin-btn,
.pin-btn:focus-visible {
  opacity: 1;
}
.pin-btn.is-done {
  opacity: 1;
  display: inline-block;
}

/* Pinned photos grid — unpin control */
.pin-wrap {
  position: relative;
}
.pin-wrap img {
  cursor: zoom-in;
}
.pin-remove-form {
  position: absolute;
  top: 2px;
  right: 2px;
  margin: 0;
  max-width: none;
}
.pin-remove {
  width: 1.4rem;
  height: 1.4rem;
  line-height: 1;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  cursor: pointer;
}

/* "My photos" strip on the profile + the /photos page */
.my-photos-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.4rem;
}
.my-photos-grid img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: var(--radius-sm);
  cursor: zoom-in;
}
.my-photos-grid.photos-page {
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
}

/* Recipe box */
.recipe-row {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  padding: 0.4rem 0;
  text-decoration: none;
  color: inherit;
  border-bottom: 1px solid var(--border);
}
.recipe-row:last-of-type {
  border-bottom: 0;
}
.recipe-thumb {
  width: 56px;
  height: 56px;
  flex: none;
  object-fit: cover;
  border-radius: var(--radius-sm);
  background: var(--surface-sunken);
}
.recipe-title {
  font-weight: 600;
}
.recipe-box-nav {
  display: flex;
  justify-content: space-between;
  margin-top: 0.6rem;
}
.recipe-box-nav button {
  background: none;
  border: 0;
  color: var(--accent-strong);
  font-weight: 600;
  cursor: pointer;
  padding: 0.2rem 0;
}

.post-recipe-title {
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 1.1rem;
  margin: 0.2rem 0;
}

/* Full-screen photo viewer */
.photo-viewer {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.9);
}
.photo-viewer[hidden] {
  display: none;
}
/* Image and controls stack as one centered group, so the control bar has a
   fixed place below the photo instead of floating over whatever part of the
   image happens to be underneath it. */
.pv-stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  max-width: 92vw;
  max-height: 92vh;
}
.pv-img {
  max-width: 92vw;
  max-height: 78vh;
  object-fit: contain;
}
.pv-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  font-size: 2.5rem;
  line-height: 1;
  width: 3rem;
  height: 3rem;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.15);
  color: #fff;
  cursor: pointer;
}
.pv-prev {
  left: 1rem;
}
.pv-next {
  right: 1rem;
}
.pv-close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  font-size: 2rem;
  line-height: 1;
  width: 2.5rem;
  height: 2.5rem;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.15);
  color: #fff;
  cursor: pointer;
}
.pv-controls {
  display: flex;
  gap: 0.75rem;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: var(--radius);
  padding: 0.6rem 0.9rem;
}
/* Filled (rather than the outlined btn-secondary used elsewhere in the
   viewer) so "Rotate" reads clearly against the dark overlay; the arrows on
   either side pick the direction. */
.pv-rotate {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  background: var(--accent);
  color: #fff;
  border-radius: var(--radius-pill);
  padding: 0.3rem;
}
.pv-rotate-arrow {
  min-height: 2.2rem;
  padding: 0 0.6rem;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: #fff;
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
}
.pv-rotate-arrow:hover {
  background: rgba(255, 255, 255, 0.2);
  color: #fff;
}
.pv-rotate-label {
  font: 600 1rem/1 var(--font-body);
  padding: 0 0.2rem;
}
/* Same filled treatment as .pv-rotate — an outlined btn-secondary pill was
   hard to make out against the dark overlay. */
.pv-pin {
  min-height: 2.2rem;
  padding: 0.5rem 1.1rem;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: #fff;
  font: 600 1rem/1 var(--font-body);
  cursor: pointer;
}
.pv-pin:hover {
  background: var(--accent-strong);
  color: #fff;
}

/* ================================================================
   Edit Family (app/templates/family_edit.html)
   Was an inline <style> block in that template; moved here so every
   rule in the app is in one file and can be searched for.
   ================================================================ */

.fe-people { list-style: none; padding: 0; margin: 0; }
.fe-people > li { padding: 0.9rem 0; border-bottom: 1px solid var(--border); }
.fe-people > li:last-child { border-bottom: 0; }
.fe-name { font-weight: 600; }
.fe-rel { margin-top: 0.35rem; font-size: 0.92rem; color: var(--ink-soft); }
.fe-rel a { color: var(--accent-strong); }
.fe-unlink { display: inline; max-width: none; margin: 0; }
.fe-unlink button {
  background: none; border: 0; color: var(--ink-soft); cursor: pointer;
  padding: 0 0.15rem; min-height: 0; font-size: 1rem; line-height: 1;
}
.fe-unlink button:hover { color: var(--danger); }
/* radio / checkbox rows read left-to-right, not stacked-and-bold */
label.choice { flex-direction: row; align-items: center; gap: 0.5rem; font-weight: 400; }
label.choice input { width: auto; min-height: 0; }
.fe-card { margin-bottom: 1.5rem; }

/* "new / already in the family" segmented toggle */
.who-seg { display: flex; max-width: 440px; border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill); overflow: hidden; }
.who-seg label { flex: 1; margin: 0; }
.who-seg input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.who-seg span { display: block; text-align: center; padding: 0.6rem 0.5rem; cursor: pointer;
  font-weight: 600; font-size: 0.9rem; color: var(--ink-soft); background: var(--surface); }
.who-seg label:first-child span { border-right: 1px solid var(--border-strong); }
.who-seg input:checked + span { background: var(--accent); color: #fff; }
.who-seg input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: -2px; }
.who-field[data-off] { opacity: 0.45; }
input:disabled, select:disabled { background: var(--surface-sunken); color: var(--ink-soft);
  cursor: not-allowed; }

/* live "X is a spouse of Y" readout — updates as the form is filled in */
.rel-preview { background: var(--tint); border: 1px solid var(--tint-border);
  border-radius: var(--radius-sm); padding: 0.85rem 1rem; }
.rel-preview-label { font-size: 0.72rem; letter-spacing: 0.09em; text-transform: uppercase;
  font-weight: 700; color: var(--ink-soft); }
.rel-preview-text { margin: 0.3rem 0 0; font-family: var(--font-head); font-size: 1.2rem;
  line-height: 1.35; color: var(--ink); }
.rel-preview-text .rel-word { color: var(--accent-strong); }

.related-how { display: flex; flex-direction: column; gap: 0.6rem; }
.rel-q { font-size: 0.95rem; font-weight: 600; }
.rel-inline { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.rel-inline select { width: auto; min-width: 8rem; }
.rel-of { color: var(--ink-soft); }
.rel-anchor-fixed { font-weight: 600; }
.related-how[data-unrelated] .rel-inline { display: none; }

/* 44px avatar, used where a card header wants a smaller face than the
 52px default (the feed composer). Replaces an inline style attribute. */
.mini-avatar.is-sm {
width: 44px;
height: 44px;
}

/* ================================================================
   Small utility classes replacing style="" attributes that were
   written inline in the templates. Dynamic values (the family tree's
   left/top percentages) are still set inline, because they genuinely
   vary per element; everything static lives here.
   ================================================================ */

.site-avatar-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
}

/* the profile header's initials fallback, sized to the 128px circle */
.profile-avatar:not(img) {
  font-size: 2.4rem;
}

.profile-claim-card { margin-top: 1.25rem; }
.profile-bio { white-space: pre-wrap; }
.profile-book { margin-top: 1.5rem; }
.pcard-action { margin-top: 0.6rem; }

/* ---------- boops (old-Facebook "poke") ---------- */

/* Split "send / choose" pill in the profile header: one bubble, left half
   sends the selected boop, the down-arrow half swaps which boop is selected. */
.boop-control {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  align-self: flex-end;
  margin-bottom: 0.4rem;
  flex-wrap: wrap;
}
.boop-split {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--accent);
  border-radius: var(--radius-pill);
  background: var(--surface);
}
.boop-split-form { margin: 0; max-width: none; display: inline-flex; }
.boop-split-send {
  min-height: 44px;
  border: 0;
  border-radius: var(--radius-pill) 0 0 var(--radius-pill);
  background: transparent;
  color: var(--accent-strong);
  font: 600 1rem/1 var(--font-body);
  padding: 0 0.9rem 0 1.15rem;
  cursor: pointer;
}
.boop-split-send:hover {
  background: var(--tint);
  color: var(--accent-strong);
}
.boop-split-menu {
  position: relative;
  display: inline-flex;
}
.boop-split-menu > summary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0 0.7rem;
  border-left: 1px solid var(--accent);
  border-radius: 0 var(--radius-pill) var(--radius-pill) 0;
  color: var(--accent-strong);
  cursor: pointer;
  list-style: none;
}
.boop-split-menu > summary::-webkit-details-marker { display: none; }
.boop-split-menu > summary:hover,
.boop-split-menu[open] > summary { background: var(--tint); }
.boop-chevron { font-size: 0.7rem; line-height: 1; }
.boop-split-list {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: 20;
  min-width: 9rem;
  margin: 0;
  padding: 0.3rem;
  list-style: none;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lift);
  display: grid;
  gap: 0.1rem;
}
.boop-split-opt {
  width: 100%;
  min-height: 40px;
  justify-content: flex-start;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--ink);
  font: 500 0.95rem/1 var(--font-body);
  padding: 0 0.7rem;
  cursor: pointer;
}
.boop-split-opt:hover {
  background: var(--tint);
  color: var(--accent-strong);
}
.boop-sent { font-size: 0.9rem; }

/* Recipient's "who booped me" panel — the standout box */
.boop-standout[hidden] { display: none; }
.boop-standout .boop-details > summary {
  cursor: pointer;
  font: 600 1rem/1.3 var(--font-body);
  color: var(--accent-strong);
}
.boop-line { margin: 0.4rem 0; }
.boop-list {
  list-style: none;
  margin: 0.6rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.5rem;
}
.boop-list li {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  padding-top: 0.5rem;
  border-top: 1px solid var(--border);
}
.boop-list li:first-child { border-top: 0; padding-top: 0; }
.boop-actions {
  display: inline-flex;
  gap: 0.4rem;
  align-items: center;
}
.boop-actions form { margin: 0; max-width: none; }
/* .btn-quiet's palette is tuned for the dark header bar; on this light card
   its near-white text and translucent border vanish. Repaint in page ink,
   same fix as `.onb .btn-quiet`. */
.boop-standout .btn-quiet {
  color: var(--ink-soft);
  border-color: var(--border-strong);
}
.boop-standout .btn-quiet:hover {
  background: var(--surface-sunken);
  color: var(--ink);
}

/* the little term/definition lists on a profile */
.kv-list { margin: 0; }
.kv-empty { margin: 0; }

.post-delete-form { max-width: none; margin-top: 0.35rem; }

.background-preview {
  width: 100%;
  max-width: 480px;
  aspect-ratio: 3 / 1;
  object-fit: cover;
  border-radius: 8px;
}

/* inline "pick which family" GET form — used by the tree and traditions pages */
.ft-family-picker {
  max-width: none;
  flex-direction: row;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 1rem;
}

/* ================================================================
   Traditions — a family page. Top half browses the approved
   traditions grouped by prompt; the bottom half is a set of
   category boxes a member opens to contribute (0..N of them),
   each with a "Skip this category" that closes it.
   ================================================================ */

/* ---- owner review queue ---- */
.tradition-review {
  margin-bottom: 2rem;
}
.tradition-review > .section-label {
  display: block;
  margin-bottom: 0.5rem;
}
.tradition-review-item {
  padding: 0.85rem 0;
}
.tradition-review-item:last-child {
  border-bottom: 0;
}
.tradition-review-head {
  margin: 0 0 0.35rem;
}
.tradition-review-body {
  margin: 0 0 0.35rem;
}
.tradition-review-actions {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.5rem;
}
.tradition-inline-form {
  max-width: none;
  margin: 0;
}

/* ---- browse: grouped answers ---- */
.tradition-group > .section-label {
  display: block;
  margin-bottom: 0.25rem;
}
.tradition-prompt-heading {
  font-size: 1.05rem;
  margin: 1rem 0 0.35rem;
}
.tradition-answer {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem;
}
.tradition-answer-body {
  flex: 1 1 12rem;
}
.tradition-answer-by {
  flex: 0 0 auto;
  font-size: 0.9rem;
}
.tradition-answer .tradition-inline-form {
  flex: 0 0 auto;
}
.tradition-remove {
  min-height: 0;
  padding: 0.2rem 0.7rem;
  font-size: 0.85rem;
}

/* ---- contribute: the category boxes ---- */
.traditions-add {
  margin-top: 1rem;
}
.traditions-boxes {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.75rem;
  margin-top: 1rem;
}
/* once JS is wired the closed boxes tile; an open one spans the row */
.traditions-boxes.is-ready {
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
}
.traditions-boxes.is-ready .tradition-box:not(.is-collapsed) {
  grid-column: 1 / -1;
}

.tradition-box {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.tradition-box-toggle {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.2rem;
  width: 100%;
  min-height: 0;
  padding: 1rem 2.4rem 1rem 1.15rem;
  background: none;
  border: 0;
  border-radius: var(--radius);
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: default;
}
.tradition-box-toggle:hover {
  background: none;
  color: var(--ink);
}
.traditions-boxes.is-ready .tradition-box-toggle {
  cursor: pointer;
}
.traditions-boxes.is-ready .tradition-box-toggle:hover {
  background: var(--surface-sunken);
}
.tradition-box-heading {
  font-family: var(--font-head);
  font-size: 1.15rem;
  font-weight: 600;
}
.tradition-box-blurb {
  font-size: 0.9rem;
}
.tradition-box-caret {
  position: absolute;
  top: 1.05rem;
  right: 1.1rem;
  color: var(--ink-soft);
  transition: transform 0.15s ease;
}
.tradition-box.is-collapsed .tradition-box-caret {
  transform: rotate(-90deg);
}
.traditions-boxes:not(.is-ready) .tradition-box-caret {
  display: none;
}

.tradition-box-body {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 0 1.15rem 1.15rem;
}
.tradition-box.is-collapsed .tradition-box-body {
  display: none;
}

.tradition-prompt {
  border-top: 1px solid var(--border);
  padding-top: 0.9rem;
}
.tradition-prompt-q {
  margin: 0;
  font-weight: 600;
}
.tradition-prompt-eg {
  margin: 0.15rem 0 0;
  font-size: 0.9rem;
}
.tradition-prompt-form {
  max-width: none;
  gap: 0.5rem;
  margin-top: 0.55rem;
}
.tradition-prompt-form textarea {
  min-height: 62px;
}
.tradition-add-btn {
  align-self: flex-start;
}

.tradition-skip {
  align-self: flex-start;
  min-height: 0;
  margin-top: 0.25rem;
  padding: 0.5rem 0;
  background: none;
  border: 0;
  color: var(--ink-soft);
  font: inherit;
  font-size: 0.9rem;
  text-decoration: underline;
  cursor: pointer;
}
.tradition-skip:hover {
  background: none;
  color: var(--accent-strong);
}
.traditions-boxes:not(.is-ready) .tradition-skip {
  display: none;
}

/* --- Onboarding -------------------------------------------------------------
   The new-family setup wizard (app/routers/onboarding.py). Reuses .card,
   .notice, .btn, .btn-secondary, .btn-quiet, .choice, .badge, .muted; the
   rules below are only the wizard-specific frame. */
.onb {
  max-width: 640px;
  margin: 0 auto;
}
.onb-rail {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1rem;
  margin: 0 0 1.25rem;
  padding: 0;
  list-style: none;
  font-size: 0.85rem;
  color: var(--ink-soft);
}
.onb-rail-step {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}
.onb-rail-dot {
  width: 0.6rem;
  height: 0.6rem;
  border-radius: var(--radius-pill);
  background: var(--border-strong);
}
.onb-rail-step.is-done .onb-rail-dot {
  background: var(--accent);
}
.onb-rail-step.is-current {
  color: var(--ink);
  font-weight: 600;
}
.onb-rail-step.is-current .onb-rail-dot {
  background: var(--accent-strong);
  box-shadow: 0 0 0 3px var(--tint);
}
.onb-card {
  padding: 1.5rem;
}
.onb-title {
  margin-top: 0;
  font-size: 1.4rem;
}
.onb-list {
  padding-left: 1.1rem;
}
.onb-list li {
  margin: 0.3rem 0;
}
.onb-examples,
.onb-cf-list {
  padding-left: 1.1rem;
}
.onb-sub {
  margin-top: 1.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--border);
}
.onb-sub h2 {
  font-size: 1.05rem;
  margin: 0 0 0.6rem;
}
.onb-inline-form {
  display: flex;
  align-items: flex-end;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.onb-tree-form fieldset {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.85rem 1rem;
  margin: 0 0 1rem;
}
.onb-tree-form legend {
  padding: 0 0.4rem;
  font-weight: 600;
}
.onb-tree-form input[type="text"] {
  display: block;
  width: 100%;
  margin: 0.35rem 0;
}
.onb-tree-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0.4rem 0;
}
.onb-tree-row input[type="text"] {
  flex: 1;
  margin: 0;
}
.onb-row-remove {
  flex: none;
  width: 2.1rem;
  height: 2.1rem;
  min-height: 0;
  padding: 0;
  border-radius: var(--radius-pill);
  background: none;
  border: 1px solid var(--border-strong);
  color: var(--ink-soft);
  font-size: 1.2rem;
  line-height: 1;
  cursor: pointer;
}
.onb-row-remove:hover {
  background: var(--surface-sunken);
  border-color: var(--danger);
  color: var(--danger);
}
/* "+ add another" — an underlined accent link, not a ghost button, so it is
   actually visible on the light card */
.onb-add-row {
  margin-top: 0.5rem;
  min-height: 0;
  padding: 0.3rem 0;
  background: none;
  border: 0;
  color: var(--accent-strong);
  font: 600 0.95rem var(--font-body);
  text-decoration: underline;
  cursor: pointer;
}
.onb-add-row:hover {
  background: none;
  color: var(--accent);
}
.onb-add-row:disabled {
  color: var(--ink-soft);
  text-decoration: none;
  cursor: default;
}
/* the remove "x" and "+ add another" only do anything with JS */
.onb-tree-form:not(.onb-js) .onb-row-remove,
.onb-tree-form:not(.onb-js) .onb-add-row {
  display: none;
}
.onb-nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  margin-top: 1.25rem;
}
.onb-nav form {
  margin: 0;
}
/* .btn-quiet's default palette is tuned for the dark header bar (near-white
   text, translucent border); on the light wizard page it disappears. Repaint
   it in page ink wherever it sits inside .onb. */
.onb .btn-quiet {
  color: var(--ink-soft);
  border-color: var(--border-strong);
}
.onb .btn-quiet:hover {
  background: var(--surface-sunken);
  color: var(--ink);
}
.onb-nudge {
  border-left-color: var(--accent);
}
.onb-nudge .btn {
  margin-top: 0.5rem;
}
.onb-nudge-link {
  margin-left: 0.5rem;
  font-size: 0.85rem;
  font-weight: 600;
}
.fe-reonboard {
  font-size: 0.9rem;
}
.onb-fieldset {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.85rem 1rem;
  margin: 0 0 1rem;
}
.onb-fieldset legend {
  padding: 0 0.4rem;
  font-weight: 600;
}
.onb-danger-choice {
  color: var(--danger);
}
.onb-danger-title {
  color: var(--danger);
}

/* ================================================================
   Reactions & comments on feed posts
   ================================================================ */

.love-control {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.post-actions .btn-secondary.is-loved {
  background: var(--tint);
  border-color: var(--tint-border);
}

/* a text-weight control for secondary actions (reveal loves, delete a comment) */
.link-like {
  min-height: 0;
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent-strong);
  font: 600 0.85rem/1 var(--font-body);
  text-decoration: underline;
  cursor: pointer;
}
.link-like:hover {
  background: none;
  color: var(--ink);
}

.loves-list:empty {
  display: none;
}
.loves-names {
  list-style: none;
  margin: 0;
  padding: 0.3rem 0 0;
  font-size: 0.85rem;
  color: var(--ink-soft);
}
.loves-names li {
  display: inline;
}
.loves-names li:not(:last-child)::after {
  content: ", ";
}

.post-comments {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.post-comments:empty {
  display: none;
}
.post-card.is-recipe .post-comments {
  width: 100%;
}

.comment-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.comment-list > li {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.comment-replies {
  margin-left: 2.6rem;
  padding-left: 0.8rem;
  border-left: 2px solid var(--border);
}

.comment {
  display: flex;
  gap: 0.6rem;
  align-items: flex-start;
}
.comment .mini-avatar {
  width: 32px;
  height: 32px;
  flex: none;
}
.comment-body {
  background: var(--surface-sunken);
  border-radius: var(--radius-sm);
  padding: 0.5rem 0.75rem;
  flex: 1;
}
.comment-meta {
  display: flex;
  gap: 0.5rem;
  align-items: baseline;
  flex-wrap: wrap;
  font-size: 0.9rem;
}
.comment-meta .post-author {
  font-size: 0.95rem;
}
.comment-meta .muted {
  font-size: 0.78rem;
}
.comment-text {
  white-space: pre-wrap;
  margin: 0.15rem 0 0;
  font-size: 0.98rem;
}
.comment-delete-form {
  margin: 0.2rem 0 0;
  max-width: none;
}

.comment-form,
.comment-reply-form {
  display: flex;
  gap: 0.5rem;
  align-items: flex-start;
  margin: 0;
  max-width: none;
}
.comment-form textarea {
  flex: 1;
  resize: vertical;
  min-height: 2.6rem;
}
.comment-reply-form {
  margin-left: 2.6rem;
}
.comment-reply-form input[type="text"] {
  flex: 1;
}
