/* JRT Family - sleek, fun, modern. Cool porcelain background, white cards
   with real depth, one characterful grotesque, and vivid line colors that
   run through everything: James coral, Reynolds emerald, Thomas amber.
   The tree itself is browsable as a chart - see the branch styles below.
   (Filename is historical; the paper metaphor is retired.) */

@font-face {
  font-family: "Bricolage";
  src: url("/fonts/Bricolage.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}

:root {
  --bg: #f4f5f9;
  --surface: #ffffff;
  --ink: #171a21;
  --ink-soft: #5c6270;
  --hairline: #e4e6ee;
  --coral: #ff5436;
  --berry: #e0356b;
  --emerald: #00a86b;
  --amber: #f7a219;
  --violet: #6d5bfa;
  --focus: #2563eb;
  --display: "Bricolage", "Avenir Next", "Trebuchet MS", system-ui, sans-serif;
  --body: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --tap: 56px;
  --measure: 34rem;
  --r-card: 22px;
  --r-ctl: 16px;
  --shadow-card: 0 1px 2px rgba(23, 26, 33, 0.05), 0 10px 30px rgba(23, 26, 33, 0.08);
  --shadow-pop: 0 4px 12px rgba(23, 26, 33, 0.10), 0 18px 44px rgba(23, 26, 33, 0.14);
  --grad-hot: linear-gradient(120deg, var(--coral), var(--berry));
  /* Line colors: worn like team colors, not archive labels. */
  --line-james: #e6432a;    --tint-james: #ffe6e0;
  --line-reynolds: #00805a; --tint-reynolds: #d9f5e9;
  --line-thomas: #b87700;   --tint-thomas: #ffefcc;
}

*, *::before, *::after { box-sizing: border-box; }

/* 100%: the reader's own default is the baseline, and we do not second-guess
   it. Never hardcode a px here.
   This was 119%, then 112%, on the theory that older relatives need bigger
   text. Wrong twice over. Somebody who wants bigger text has already set it
   in their browser or their phone, and 100% honours that exactly - inflating
   the root overrides a choice they made on purpose. It is also a blunt
   instrument: every rem below multiplies it, so it grew the tab labels and
   captions that were already fine along with the body copy that needed help,
   and the headings came out shouting.
   Body copy is sized deliberately below instead, and the small chrome text
   carries an explicit floor rather than riding a global multiplier. */
html { -webkit-text-size-adjust: 100%; font-size: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--body);
  font-size: 1rem;
  line-height: 1.55;
  padding: 0 1.1rem env(safe-area-inset-bottom) 1.1rem;
}

main { max-width: var(--measure); margin: 0 auto; }

h1 {
  font-family: var(--display);
  font-size: 1.85rem;
  line-height: 1.1;
  font-weight: 700;
  letter-spacing: -0.018em;
  margin: 1.3rem 0 0.3rem;
  text-wrap: balance;
}

h2 {
  font-family: var(--display);
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--ink);
  margin: 2.1rem 0 0.6rem;
}

a { color: var(--berry); text-underline-offset: 0.15em; }
a:hover { color: #b02451; }

:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }

button, .row, .btn { min-height: var(--tap); font-size: 1rem; font-family: var(--body); }

/* Primary actions ride the hot gradient. */
.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  width: 100%;
  padding: 0 1.5rem;
  border: 0;
  border-radius: 999px;
  background: var(--grad-hot);
  color: #fff;
  font-weight: 700;
  letter-spacing: 0.005em;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(224, 53, 107, 0.35);
  transition: transform 90ms ease, box-shadow 90ms ease;
}
.btn:active { transform: scale(0.985); box-shadow: 0 2px 6px rgba(224, 53, 107, 0.3); }
.btn--quiet {
  background: var(--surface);
  color: var(--ink);
  border: 1.5px solid var(--hairline);
  box-shadow: var(--shadow-card);
}
.btn--quiet:active { transform: scale(0.985); }

/* A button that sits beside others instead of owning its own line. Used on
   the profile header, where three full-width stacked buttons pushed the
   family down below the fold. */
.btn--pill {
  width: auto;
  min-height: 44px;
  padding: 0 1.1rem;
  font-size: 0.95rem;
  box-shadow: 0 2px 8px rgba(224, 53, 107, 0.3);
}
.btn--pill.btn--quiet { box-shadow: none; }

/* People rows: avatar chip, stacked text, chevron. */
.row {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  width: 100%;
  padding: 0.55rem 0.75rem;
  margin: 0 -0.75rem;
  width: calc(100% + 1.5rem);
  border: 0;
  border-radius: var(--r-ctl);
  background: none;
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: background 90ms ease;
}
.row:active { background: rgba(23, 26, 33, 0.05); }

.row__text { display: flex; flex-direction: column; min-width: 0; }
.row__name { font-family: var(--display); font-weight: 600; font-size: 1.05rem; line-height: 1.3; }
.row__life { color: var(--ink-soft); font-size: 0.92rem; font-variant-numeric: oldstyle-nums; }
.row__go { margin-left: auto; color: #c3c7d4; font-size: 1.5rem; line-height: 1; padding-left: 0.5rem; }

/* Avatar chips: squircles in line colors. */
.mono {
  flex: none;
  width: 52px;
  height: 52px;
  border-radius: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.1rem;
  letter-spacing: 0.02em;
  background: #e9ebf3;
  color: var(--ink-soft);
}
.mono--james { background: var(--tint-james); color: var(--line-james); }
.mono--reynolds { background: var(--tint-reynolds); color: var(--line-reynolds); }
.mono--thomas { background: var(--tint-thomas); color: var(--line-thomas); }

.life { color: var(--ink-soft); font-size: 1rem; margin: 0 0 1rem; font-variant-numeric: oldstyle-nums; }

.portrait {
  margin: 0 0 0.75rem;
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  overflow: hidden;
  background: var(--surface);
}
.portrait img { display: block; width: 100%; height: auto; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}

.field {
  width: 100%;
  min-height: var(--tap);
  font-size: 1.05rem;
  padding: 0 1.15rem;
  border: 1.5px solid var(--hairline);
  border-radius: var(--r-ctl);
  background: var(--surface);
  color: var(--ink);
  font-family: var(--body);
  box-shadow: var(--shadow-card);
}
.field:focus { border-color: var(--berry); outline: none; box-shadow: 0 0 0 3px rgba(224, 53, 107, 0.15); }
.field--lead { font-size: 1.1rem; }

.change { border-bottom: 1px solid var(--hairline); padding: 0.9rem 0; }
.change__what { margin: 0 0 0.3rem; }
.change__who { margin: 0 0 0.6rem; }

.sheet { display: flex; flex-direction: column; gap: 0.9rem; padding-top: 0.5rem; }
.sheet .btn { margin: 0; }

.masthead {
  font-family: var(--display);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-size: 0.78rem;
  color: var(--ink-soft);
  text-align: center;
  margin: 1.3rem 0 0.4rem;
}

/* ------------------------------------------------------------------ */
/* Welcome: a big friendly hero on soft color, not a book cover. */
.welcome {
  min-height: 100dvh;
  margin: 0 -1.1rem;
  padding: 3rem 1.4rem calc(3rem + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  justify-content: center;
  text-align: center;
  /* The washes take their colors from the logo itself: its pink and its
     green, with a little amber warmth at the foot. */
  background:
    radial-gradient(62% 36% at 20% 6%, rgba(224, 125, 146, 0.22), transparent 70%),
    radial-gradient(52% 30% at 86% 22%, rgba(46, 139, 74, 0.14), transparent 70%),
    radial-gradient(56% 32% at 50% 94%, rgba(247, 162, 25, 0.14), transparent 70%),
    var(--bg);
}

.welcome__mark { margin: 0 auto 1.4rem; width: 84px; height: 84px; }
.welcome__mark svg { display: block; width: 100%; height: 100%; }

/* The logo plate: the old-school artwork, framed like the treasure it is. */
.welcome__logo {
  margin: 0 auto 1.5rem;
  width: min(11.5rem, 52vw);
  border-radius: 20px;
  overflow: hidden;
  box-shadow: var(--shadow-pop);
  transform: rotate(-2deg);
}
.welcome__logo img { display: block; width: 100%; height: auto; }

.welcome__names {
  font-family: var(--display);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-size: 0.82rem;
  color: var(--ink-soft);
  margin: 0 0 1.1rem;
}

.welcome h1 {
  font-size: 2.5rem;
  font-weight: 800;
  margin: 0 0 1rem;
}
.welcome h1 em {
  font-style: normal;
  background: var(--grad-hot);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.welcome .life { font-size: 1.08rem; margin-bottom: 2.2rem; }
.welcome .btn { max-width: 22rem; margin: 0 auto; }
.welcome .life:last-child { margin: 1.5rem auto 0; max-width: 24rem; }

/* ------------------------------------------------------------------ */
/* The signed-in person's card on Home. */
.me {
  text-align: center;
  margin: 1.4rem 0 0.5rem;
  padding: 1.5rem 1.25rem 1.4rem;
  background: var(--surface);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
}
.me__photo { max-width: 13rem; margin: 0 auto 1rem; }
.me h1 { margin: 0.3rem 0 0.1rem; font-size: 1.7rem; }
.me .life { margin-bottom: 1.1rem; }
.me .btn { max-width: 16rem; margin: 0 auto; }
.me .btn + .btn { margin-top: 0.6rem; }

.person__dates { font-size: 1.1rem; }

/* --- The profile header -------------------------------------------------
   A face, a name, the dates, and what to do next - the shape every phone
   has taught the family to read. The old page opened with a full-bleed
   photograph and four stacked buttons, which pushed the actual family off
   the first screen. */
.profile {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.35rem;
  padding: 0.5rem 0 1.25rem;
}

.avatar {
  width: 132px;
  height: 132px;
  border-radius: 50%;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface);
  /* The ring reads as a portrait frame at any size and hides the seam
     where a photograph's own edge meets the page. */
  box-shadow: 0 0 0 4px var(--surface), 0 0 0 6px var(--hairline), var(--shadow-card);
  margin-bottom: 0.6rem;
}
.avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* No photograph: the same tinted initials the rest of the app uses for
   this person, sized up. A page with no photo still gets a face-shaped
   anchor rather than a hole. */
.avatar--mono {
  font-family: var(--display);
  font-weight: 750;
  font-size: 3rem;
  letter-spacing: 0.01em;
  background: #e9ebf3;
  color: var(--ink-soft);
}
.avatar--mono.mono--james { background: var(--tint-james); color: var(--line-james); }
.avatar--mono.mono--reynolds { background: var(--tint-reynolds); color: var(--line-reynolds); }
.avatar--mono.mono--thomas { background: var(--tint-thomas); color: var(--line-thomas); }

.profile__name {
  margin: 0;
  font-size: 1.7rem;
  line-height: 1.12;
}
.profile__life {
  margin: 0;
  font-size: 1.05rem;
  color: var(--ink-soft);
  font-variant-numeric: oldstyle-nums;
}
.profile__place { margin: 0; color: var(--ink-soft); font-size: 0.98rem; }
.profile__also { margin: 0.1rem 0 0; color: var(--ink-soft); font-size: 0.95rem; }

.profile__acts {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 0.85rem;
}
.profile__acts--left { justify-content: flex-start; margin-top: 0.2rem; }

.profile__tools { text-align: center; margin-top: 1.25rem; }

/* Family, one card per relationship, counted in its own header. */
.famcard { padding-bottom: 0.6rem; }
.famcard__title {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin: 0 0 0.35rem;
  font-size: 1.15rem;
}
.famcard__count {
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--ink-soft);
  background: #eef0f6;
  border-radius: 999px;
  padding: 0.1rem 0.55rem;
  font-variant-numeric: tabular-nums;
}
.famcard .row { margin-left: -0.35rem; margin-right: -0.35rem; }

.story { margin: 0 0 0.6rem; }

/* The paste box: monospace so columns line up and the treasurer can see at
   a glance whether the sheet came across as columns or as one mush. */
.import__box {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.85rem;
  line-height: 1.4;
  min-height: 0;
  white-space: pre;
  overflow-x: auto;
}
.import__plan { margin-top: 0.6rem; }
.import__plan .life { margin-bottom: 0.5rem; }

/* The line under a field explaining what it will accept. Tighter than a
   free-standing .life so it reads as part of the control above it. */
.field__help { margin: -0.55rem 0 1rem; font-size: 0.9rem; }

/* Photographs as a grid of squares. Stacked full-width figures turned two
   snapshots into a page nobody scrolled to the bottom of. */
.gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.5rem;
  margin-top: 0.6rem;
}
.gallery__cell {
  margin: 0;
  aspect-ratio: 1;
  border-radius: 14px;
  overflow: hidden;
  background: #eef0f6;
}
.gallery__cell img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* The cells and the portrait are buttons now, so they need the button
   defaults stripped back off - min-height in particular would break the
   square grid. */
.gallery__cell, .avatar {
  border: 0;
  padding: 0;
  min-height: 0;
  cursor: pointer;
  font: inherit;
}
.gallery__cell:active, .avatar:active { transform: scale(0.985); }

.photo__full {
  margin: 0 0 1rem;
  border-radius: var(--r-card);
  overflow: hidden;
  background: var(--surface);
  box-shadow: var(--shadow-card);
}
.photo__full img { display: block; width: 100%; height: auto; }
.photo__title { font-size: 1.5rem; margin: 0 0 0.2rem; }
.photo__tag { display: flex; align-items: center; gap: 0.5rem; }
.photo__tag .row { flex: 1; min-width: 0; }

.recipe__items, .recipe__steps { margin: 0.2rem 0 0; padding-left: 1.3rem; }
.recipe__items li, .recipe__steps li { margin-bottom: 0.45rem; }
.recipe__steps li { padding-left: 0.2rem; }

/* Cards that invite: the nominations callout. */
.callout {
  background: var(--grad-hot);
  color: #fff;
  border-radius: var(--r-card);
  padding: 1.4rem 1.3rem 1.35rem;
  box-shadow: 0 10px 30px rgba(224, 53, 107, 0.3);
}
.callout p { color: rgba(255, 255, 255, 0.9); margin: 0 0 1rem; font-size: 1rem; }
.callout .callout__title {
  font-family: var(--display);
  font-size: 1.45rem;
  font-weight: 750;
  color: #fff;
  margin: 0 0 0.35rem;
}
.callout .btn { background: #fff; color: var(--berry); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.18); }

/* ------------------------------------------------------------------ */
/* THE BRANCH: the family as a chart. Three tiers - parents above,
   you (and partners) in the middle, children below - drawn with real
   connector lines and browsed by tapping any card to re-center on them. */

.branch { padding-bottom: 2rem; }
.branch__title { text-align: center; }
.branch__hint { text-align: center; color: var(--ink-soft); font-size: 0.92rem; margin: 0.2rem 0 1.2rem; }

.branch__chart { position: relative; }

/* The connector layer is drawn by branch.js after layout. */
.branch__wires {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 0;
}
.branch__wires path {
  fill: none;
  stroke: #c9cddd;
  stroke-width: 2.5;
  stroke-linecap: round;
}

/* Full-bleed scrollable tiers. justify-content: center clips the left
   edge of an overflowing flex row (it centers the OVERFLOW too), so
   centering is done with auto margins on the end cards instead: centered
   when the tier fits, scrollable edge to edge when it does not. */
.branch__chart { margin: 0 -1.1rem; }
.tier {
  position: relative;
  z-index: 1;
  display: flex;
  gap: 0.8rem;
  padding: 0.9rem 1.1rem;
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
}
.tier > :first-child { margin-left: auto; }
.tier > :last-child { margin-right: auto; }
.tier::-webkit-scrollbar { display: none; }
.tier--focus { padding: 1.1rem 0; }

/* A person in the chart. */
.node {
  flex: none;
  width: 8.4rem;
  padding: 0.85rem 0.6rem 0.8rem;
  border: 0;
  border-radius: 20px;
  background: var(--surface);
  box-shadow: var(--shadow-card);
  color: inherit;
  font-family: var(--body);
  text-align: center;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.45rem;
  transition: transform 90ms ease, box-shadow 90ms ease;
}
.node:active { transform: scale(0.97); }
.node .mono { width: 58px; height: 58px; border-radius: 20px; font-size: 1.2rem; }
.node__name { font-family: var(--display); font-weight: 650; font-size: 0.98rem; line-height: 1.2; }
.node__life { color: var(--ink-soft); font-size: 0.8rem; font-variant-numeric: oldstyle-nums; }

/* You (or whoever the chart is centered on): bigger, ringed in gradient. */
.node--focus {
  width: 10.2rem;
  padding: 1.05rem 0.7rem 1rem;
  box-shadow: var(--shadow-pop);
  position: relative;
  cursor: default;
}
.node--focus::before {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: 23px;
  padding: 3px;
  background: var(--grad-hot);
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
}
.node--focus .mono { width: 72px; height: 72px; border-radius: 24px; font-size: 1.5rem; }
.node--focus .node__name { font-size: 1.12rem; }

/* An empty slot keeps the chart honest about what is not recorded. */
.node--ghost {
  background: transparent;
  border: 2px dashed #d4d7e3;
  box-shadow: none;
  color: var(--ink-soft);
  justify-content: center;
  min-height: 7.5rem;
}

.tier__label {
  position: relative;
  z-index: 1;
  text-align: center;
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0.4rem 0 0;
}

/* ------------------------------------------------------------------ */
/* THE WHOLE FAMILY: a collapsible outline tree - oldest known ancestors
   at the top, descendants nested and indented beneath, connector lines
   down the left edge. Native <details>/<summary> disclosure per branch,
   not a wire-drawn canvas - this is a much larger rendering problem than
   the branch chart's three tiers and does not need pan/zoom to read. */

.familytree__list {
  list-style: none;
  margin: 0;
  padding: 0;
}
/* A node's children live inside its .familytree__branch details element -
   that nesting is what carries the indent and the connector line down. */
.familytree__branch > .familytree__list {
  margin-left: 1.1rem;
  padding-left: 1rem;
  border-left: 2px solid var(--hairline);
}
.familytree__item { margin-bottom: 0.15rem; }
.familytree__row { display: flex; flex-direction: column; }

.familytree__toggle {
  display: flex;
  align-items: center;
  min-height: var(--tap);
  padding: 0 0.75rem;
  list-style: none;
  color: var(--ink-soft);
  cursor: pointer;
  user-select: none;
  transition: transform 90ms ease;
}
.familytree__toggle::-webkit-details-marker { display: none; }
.familytree__caret { display: inline-block; transition: transform 90ms ease; }
.familytree__count {
  margin-left: 0.5rem;
  font-family: var(--display);
  font-weight: 650;
  font-size: 0.92rem;
}
.familytree__branch[open] > .familytree__toggle .familytree__caret { transform: rotate(90deg); }

/* ------------------------------------------------------------------ */
@media (prefers-reduced-motion: no-preference) {
  main > section > *, main > article > * {
    animation: rise 0.4s cubic-bezier(0.2, 0.7, 0.3, 1) both;
  }
  main > section > *:nth-child(1), main > article > *:nth-child(1) { animation-delay: 0ms; }
  main > section > *:nth-child(2), main > article > *:nth-child(2) { animation-delay: 40ms; }
  main > section > *:nth-child(3), main > article > *:nth-child(3) { animation-delay: 80ms; }
  main > section > *:nth-child(4), main > article > *:nth-child(4) { animation-delay: 120ms; }
  main > section > *:nth-child(5), main > article > *:nth-child(5) { animation-delay: 160ms; }
  main > section > *:nth-child(n+6), main > article > *:nth-child(n+6) { animation-delay: 200ms; }
}
@keyframes rise {
  from { opacity: 0; transform: translateY(0.45rem); }
  to { opacity: 1; transform: none; }
}

/* ------------------------------------------------------------------ */
/* Reunion nominations, in the same system: white cards, big friendly
   counts, the hot gradient on every primary action. */

.cards { display: flex; flex-direction: column; gap: 0.9rem; }

.card {
  background: var(--surface);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  padding: 1.15rem 1.15rem 1.2rem;
}

.card__head { display: flex; align-items: baseline; justify-content: space-between; gap: 0.75rem; }
.card__place { font-family: var(--display); font-size: 1.45rem; line-height: 1.15; font-weight: 750; margin: 0; }
.card__count { margin: 0; text-align: right; line-height: 1.05; }
.card__count strong {
  display: block;
  font-family: var(--display);
  font-size: 1.6rem;
  font-weight: 800;
  background: var(--grad-hot);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.card__count span {
  display: block;
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.card__credit { margin: 0.35rem 0 0; color: var(--ink-soft); font-size: 0.92rem; }
.card__host { margin: 0.5rem 0 0; color: var(--emerald); font-weight: 600; font-size: 0.95rem; }
.quote { font-size: 1.05rem; line-height: 1.5; margin: 0.6rem 0 0; color: var(--ink); }
.card .btn { margin-top: 0.9rem; }
.card .btn--quiet { border-color: var(--hairline); }

#nominateform label,
#mergeform label {
  display: block;
  margin: 1.1rem 0 0.35rem;
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.9rem;
  color: var(--ink);
}

.field--area { min-height: 5.5rem; padding: 0.7rem 1.15rem; line-height: 1.5; resize: vertical; }

.check {
  display: flex !important;
  align-items: flex-start;
  gap: 0.75rem;
  margin: 1.1rem 0 0 !important;
  padding: 0.9rem 1rem;
  background: var(--surface);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  min-height: var(--tap);
  font-size: 1rem !important;
  color: var(--ink) !important;
  font-weight: 400 !important;
}
.check input { width: 1.4rem; height: 1.4rem; margin-top: 0.2rem; flex: 0 0 auto; accent-color: var(--berry); }
.check .life { display: block; margin: 0.2rem 0 0; font-size: 0.95rem; }

.suggestions {
  background: var(--surface);
  border-radius: var(--r-ctl);
  box-shadow: var(--shadow-pop);
  margin-top: 0.4rem;
  overflow: hidden;
}
.suggestion {
  display: block;
  width: 100%;
  min-height: var(--tap);
  padding: 0.6rem 1.1rem;
  border: 0;
  border-bottom: 1px solid var(--hairline);
  background: none;
  color: inherit;
  text-align: left;
  cursor: pointer;
  font-family: var(--body);
  font-size: 1rem;
}
.suggestion:last-child { border-bottom: 0; }
.suggestion:active { background: rgba(23, 26, 33, 0.05); }
.suggestion strong { font-family: var(--display); font-weight: 650; font-size: 1.08rem; display: block; }
.suggestion span { color: var(--ink-soft); font-size: 0.9rem; }

.note {
  background: var(--surface);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  padding: 1.1rem;
  margin: 1.5rem 0;
}
.note p { margin: 0 0 0.6rem; }
.note .btn { margin-top: 0.3rem; }

.picks { border: 0; padding: 0; margin: 1rem 0 0; display: flex; flex-direction: column; gap: 0.8rem; }
.pick {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 1rem;
  background: var(--surface);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  border: 2px solid transparent;
  min-height: var(--tap);
  cursor: pointer;
}
.pick--chosen { border-color: var(--berry); }
.pick input { width: 1.5rem; height: 1.5rem; margin-top: 0.3rem; flex: 0 0 auto; accent-color: var(--berry); }
.pick__chosen {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--berry);
}

.winner {
  background: var(--grad-hot);
  color: #fff;
  border-radius: var(--r-card);
  box-shadow: 0 12px 34px rgba(224, 53, 107, 0.32);
  padding: 1.7rem 1.2rem;
  text-align: center;
  margin-top: 1.4rem;
}
.winner__label {
  margin: 0;
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.85);
}
.winner__place { font-size: 2.4rem; margin: 0.4rem 0 0.7rem; color: #fff; }
.winner p:last-child { margin: 0; color: rgba(255, 255, 255, 0.9); }

.bars { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.9rem; }
.bar__head {
  display: flex;
  justify-content: space-between;
  gap: 0.75rem;
  margin: 0 0 0.3rem;
  font-family: var(--display);
  font-weight: 650;
  font-size: 1.05rem;
}
.bar__track { height: 0.8rem; background: #e7e9f1; border-radius: 999px; overflow: hidden; }
.bar__fill { height: 100%; background: #aab0c2; border-radius: 999px; }
.bar__fill--top { background: var(--grad-hot); }

/* ------------------------------------------------------------------ */
/* Add a person: one question per block, a preview that comes alive as
   the name is typed, segmented choices instead of dropdowns. */

.add form label,
.add fieldset legend {
  display: block;
  margin: 1.2rem 0 0.4rem;
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.95rem;
}
.add__optional { color: var(--ink-soft); font-weight: 400; font-size: 0.85rem; }
.field--short { max-width: 11rem; }

.add__preview {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.9rem 1rem;
  background: var(--surface);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  margin: 0.4rem 0 0.6rem;
}
.add__previewname { font-family: var(--display); font-weight: 650; font-size: 1.2rem; }

.seg { border: 0; padding: 0; margin: 0; }
.seg__opt { display: inline-flex; margin: 0 0.5rem 0.5rem 0; }
.seg--stack .seg__opt { display: flex; margin: 0 0 0.5rem; }
.seg__opt input { position: absolute; opacity: 0; }
.seg__opt span {
  display: flex;
  align-items: center;
  min-height: var(--tap);
  padding: 0 1.2rem;
  border-radius: 999px;
  background: var(--surface);
  border: 1.5px solid var(--hairline);
  box-shadow: var(--shadow-card);
  font-size: 1rem;
  cursor: pointer;
  transition: border-color 90ms ease, background 90ms ease;
}
.seg--stack .seg__opt span { width: 100%; }
.seg__opt input:checked + span {
  border-color: var(--berry);
  background: #fdeef4;
  font-weight: 600;
}
.seg__opt input:focus-visible + span { outline: 3px solid var(--focus); outline-offset: 2px; }

/* The branch chart's empty parent slot is a real invitation now. */
.node--ghost { cursor: pointer; }

/* ------------------------------------------------------------------ */
/* The approver console: a small dashboard, not a pile of prose. */

.console h1 { text-align: left; margin-bottom: 0.9rem; }

.stats { display: flex; gap: 0.7rem; margin: 0 0 0.5rem; }
.stat {
  flex: 1;
  background: var(--surface);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  padding: 0.85rem 0.5rem 0.8rem;
  text-align: center;
}
.stat strong {
  display: block;
  font-family: var(--display);
  font-weight: 800;
  font-size: 1.7rem;
  line-height: 1.1;
}
.stat span {
  display: block;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-top: 0.15rem;
}
.stat--hot strong {
  background: var(--grad-hot);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* All-clear rows: a green dot and a calm sentence, inside a real card. */
.clear { display: flex; align-items: flex-start; gap: 0.85rem; }
.clear__dot {
  flex: none;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--emerald);
  margin-top: 0.45rem;
  box-shadow: 0 0 0 4px rgba(0, 168, 107, 0.15);
}
.clear__title { font-family: var(--display); font-weight: 700; font-size: 1.1rem; margin: 0 0 0.15rem; }
.clear__sub { color: var(--ink-soft); font-size: 0.95rem; margin: 0; }

/* The phase block inside the campaign card. */
.phase { display: flex; align-items: flex-start; gap: 0.85rem; margin-bottom: 0.8rem; }
.phase__dot {
  flex: none;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--amber);
  margin-top: 0.4rem;
  box-shadow: 0 0 0 4px rgba(247, 162, 25, 0.18);
  animation: breathe 2.4s ease-in-out infinite;
}
.phase__dot--done { background: #aab0c2; box-shadow: none; animation: none; }
@media (prefers-reduced-motion: reduce) { .phase__dot { animation: none; } }
@keyframes breathe {
  0%, 100% { box-shadow: 0 0 0 4px rgba(247, 162, 25, 0.18); }
  50% { box-shadow: 0 0 0 8px rgba(247, 162, 25, 0.08); }
}
.phase__title { font-family: var(--display); font-weight: 700; font-size: 1.15rem; margin: 0; }
.phase__sub { color: var(--ink-soft); font-size: 0.92rem; margin: 0.1rem 0 0; }
.phase__hint { color: var(--ink-soft); font-size: 0.88rem; text-align: center; margin: 0.6rem 0 0; }

.console__tools { margin-top: 1.6rem; display: flex; flex-direction: column; gap: 0.7rem; }
.console__tools .life { margin: 0; text-align: center; }

/* ------------------------------------------------------------------ */
/* The app shell: five tabs, fixed to the bottom, words under icons. */

body.has-tabs { padding-bottom: calc(4.6rem + env(safe-area-inset-bottom)); }

.tabs {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 50;
  display: flex;
  justify-content: space-around;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-top: 1px solid var(--hairline);
  padding: 0.35rem 0.3rem calc(0.35rem + env(safe-area-inset-bottom));
}

.tab {
  flex: 1;
  max-width: 6.5rem;
  min-height: var(--tap);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.15rem;
  border-radius: 14px;
  color: var(--ink-soft);
  text-decoration: none;
  font-family: var(--display);
  font-weight: 650;
  font-size: 0.8rem;
  letter-spacing: 0.02em;
  transition: background 90ms ease, color 90ms ease;
}
.tab svg { width: 24px; height: 24px; }
.tab:active { background: rgba(23, 26, 33, 0.06); }

/* The badge. Positioned on a wrapper around the icon rather than the tab
   itself, so it sits on the glyph and not out by the word underneath. The
   ring is the bar's own background, which is what keeps the dot readable
   where it overlaps a stroke of the icon. */
.tab__icon {
  position: relative;
  display: inline-flex;
  line-height: 0;
}
.tab__badge {
  position: absolute;
  top: -2px;
  right: -3px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--coral);
  box-shadow: 0 0 0 2px var(--surface);
}

/* Owing money is worth noticing, not worth alarming anybody. Warm tint,
   coral edge, same card shape as everything else. */
.card--owed {
  border-color: var(--coral);
  background: linear-gradient(180deg, rgba(255, 84, 54, 0.07), rgba(255, 84, 54, 0.02));
}
.owed__how {
  white-space: pre-line;
  font-family: var(--display);
  font-weight: 650;
  margin: 0.5rem 0;
  color: var(--ink);
}

/* Active carries weight and a mark, never color alone. */
.tab--active {
  color: var(--berry);
  font-weight: 750;
}
.tab--active::after {
  content: "";
  width: 1.1rem;
  height: 3px;
  border-radius: 2px;
  background: var(--grad-hot);
  margin-top: 0.1rem;
}

/* More-screen rows read as menu items: the label in the UI face. */
.row__name--sans { font-family: var(--display); font-weight: 650; font-size: 1.05rem; }

/* ------------------------------------------------------------------ */
/* Dues: pills for standing, ledger rows, inline year form. */

.pill {
  margin-left: auto;
  flex: none;
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.82rem;
  padding: 0.35rem 0.75rem;
  border-radius: 999px;
  white-space: nowrap;
}
.pill--paid { background: var(--tint-reynolds); color: var(--line-reynolds); }
.pill--owes { background: #ffe3e0; color: #c22315; }

.ledger {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.55rem 0.1rem;
  border-bottom: 1px solid var(--hairline);
  min-height: var(--tap);
}
.ledger:last-child { border-bottom: 0; }
.ledger--voided .row__name, .ledger--voided .ledger__amount { text-decoration: line-through; color: var(--ink-soft); }
.ledger__amount {
  margin-left: auto;
  font-family: var(--display);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.ledger__amount--in { color: var(--line-reynolds); }
.ledger__void {
  flex: none;
  border: 1.5px solid var(--hairline);
  background: var(--surface);
  border-radius: 999px;
  min-height: 2.4rem;
  padding: 0 0.9rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--ink-soft);
  cursor: pointer;
}

.dues__inline { display: flex; gap: 0.6rem; flex-wrap: wrap; align-items: center; }
.dues__inline .field--short { max-width: 7rem; }
.dues__inline .btn { flex: 1; min-width: 12rem; }

/* Open e-board seats read as invitations, not errors. */
.eboard--open { color: var(--ink-soft); font-weight: 500; font-style: italic; }
#officesform label { display: block; margin: 0.9rem 0 0.35rem; font-family: var(--display); font-weight: 700; font-size: 0.9rem; }

/* ---- Faces -------------------------------------------------------------
   One question filling the screen. The face is the evidence, so it gets the
   space; the names under it are the answer, so they get the tap targets.  */

.faces__progress { font-variant-numeric: tabular-nums; }

.facecard {
  background: var(--surface);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  padding: 1.1rem;
  margin: 0 0 1.4rem;
}

/* The crop is a window onto the full photograph: the img inside is scaled
   and offset so the face lands centred. overflow:hidden is what makes it a
   window rather than a very large picture, so it is load-bearing. */
.facecrop {
  display: block;
  position: relative;
  overflow: hidden;
  border-radius: var(--r-ctl);
  background: var(--hairline);
  aspect-ratio: 1 / 1;
  width: 100%;
  max-width: 20rem;
  margin: 0 auto;
}
.facecrop img {
  display: block;
  transform-origin: top left;
  /* No max-width:100% here on purpose - the crop works BY overflowing. */
}
.facecrop--small {
  width: 3.6rem;
  max-width: 3.6rem;
  margin: 0;
  border-radius: 12px;
  flex: none;
}

/* The other photographs the same person turns up in. Evidence that the
   group is right, at a glance, without another tap. */
.facestrip {
  display: flex;
  gap: 0.45rem;
  overflow-x: auto;
  padding: 0.2rem 0 0.4rem;
  margin: 0.7rem 0 0;
  scrollbar-width: none;
}
.facestrip::-webkit-scrollbar { display: none; }

.facecard__count {
  margin: 0.85rem 0 0;
  text-align: center;
  color: var(--ink-soft);
  font-size: 0.9rem;
  font-weight: 600;
}
.facecard__ask {
  font-family: var(--display);
  font-size: 1.35rem;
  font-weight: 700;
  text-align: center;
  margin: 0.9rem 0 0.8rem;
}
.facecard__note:empty { display: none; }

.facesuggests { display: flex; flex-direction: column; gap: 0.5rem; }

/* A suggestion is a name over a hedge, never a name alone: the app is
   guessing, and the button has to say so without shouting it. */
.facesuggest {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.1rem;
  width: 100%;
  min-height: var(--tap);
  text-align: left;
  padding: 0.55rem 1rem;
}
.facesuggest__name { font-family: var(--display); font-weight: 700; font-size: 1.02rem; }
.facesuggest__hint { font-size: 0.78rem; color: var(--ink-soft); font-weight: 500; }

.faceactions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin: 0.9rem 0 0;
}
.faceactions .btn { flex: 1; min-width: 8rem; font-size: 0.85rem; }

/* ---- The cookbook ------------------------------------------------------
   A community recipe box: courses are the tab dividers, dishes are the
   cards, and every card says whose kitchen it came from. The one list in
   the app where the display face carries the item names. */

.course { margin: 0 0 1.5rem; }
.course__tab {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--display);
  font-size: 0.95rem;
  font-weight: 700;
  margin: 0;
  padding: 0.45rem 1rem 0.55rem;
  border-radius: 14px 14px 0 0;
  position: relative;
  top: 1px;
}
.course__count { font-size: 0.78rem; font-weight: 600; opacity: 0.75; }

/* The divider's color says which part of the meal you are in. Tabs are
   tinted like the index tabs in a real box - color on color, quiet. */
.course--coral   .course__tab { background: #ffe3dd; color: #b32a12; }
.course--berry   .course__tab { background: #fbdde8; color: #ad2454; }
.course--emerald .course__tab { background: #d9f5e9; color: #00714b; }
.course--amber   .course__tab { background: #ffefcc; color: #8f5d00; }
.course--violet  .course__tab { background: #e6e2ff; color: #4a3bd6; }
.course--plain   .course__tab { background: var(--hairline); color: var(--ink-soft); }

.course__stack {
  background: var(--surface);
  border-radius: 0 var(--r-card) var(--r-card) var(--r-card);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}

.dish {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  min-height: var(--tap);
  padding: 0.8rem 1rem;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--hairline);
  text-align: left;
  cursor: pointer;
  font: inherit;
  color: inherit;
}
.dish:last-child { border-bottom: 0; }
.dish__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.12rem; }
.dish__name {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.08rem;
  line-height: 1.25;
}
/* One line, however long the cook wrote. The card is a listing, not the
   recipe; the full story is one tap away. */
.dish__kitchen {
  font-size: 0.83rem;
  color: var(--ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.dish__waiting { font-size: 0.78rem; color: #8f5d00; font-style: italic; }
.dish__cook { flex: none; }

/* ---- Cooking from one --------------------------------------------------
   Built for a phone propped against the flour bag. */

.cook__title {
  font-family: var(--display);
  font-size: 2.1rem;
  font-weight: 800;
  line-height: 1.1;
  margin: 0.4rem 0 0.2rem;
}
.cook__kitchen {
  font-family: var(--display);
  font-size: 1rem;
  font-weight: 600;
  color: var(--berry);
  margin: 0 0 0.6rem;
}
.cook__hint { font-size: 0.8rem; color: var(--ink-soft); margin: 0.1rem 0 0.5rem; }

.cook__facts {
  display: flex;
  gap: 0.6rem;
  margin: 0.9rem 0 1.1rem;
}
.fact {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.1rem;
  background: var(--surface);
  border-radius: var(--r-ctl);
  box-shadow: var(--shadow-card);
  padding: 0.6rem 0.4rem 0.55rem;
}
.fact__value {
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.98rem;
  font-variant-numeric: tabular-nums;
  text-align: center;
}
.fact__label {
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Each ingredient is a tap: added to the bowl, crossed off the list. State
   lives only on screen and resets with the page, which is exactly the
   lifetime of one cooking session. */
.recipe__items--check { list-style: none; padding-left: 0; margin: 0; }
.recipe__items--check li { margin: 0; }
.ingcheck {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  width: 100%;
  min-height: 2.6rem;
  padding: 0.35rem 0.2rem;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--hairline);
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
li:last-child > .ingcheck { border-bottom: 0; }
.ingcheck::before {
  content: "";
  flex: none;
  width: 1.15rem;
  height: 1.15rem;
  border: 2px solid var(--hairline);
  border-radius: 50%;
  transition: background 0.15s, border-color 0.15s;
}
.ingcheck[aria-pressed="true"] { color: var(--ink-soft); text-decoration: line-through; }
.ingcheck[aria-pressed="true"]::before {
  background: var(--emerald);
  border-color: var(--emerald);
}
@media (prefers-reduced-motion: reduce) {
  .ingcheck::before { transition: none; }
}

/* Steps numbered big enough to find again with buttered hands. */
.recipe__steps { list-style: none; counter-reset: step; padding-left: 0; margin: 0.3rem 0 0; }
.recipe__steps li {
  counter-increment: step;
  position: relative;
  padding: 0.15rem 0 0.8rem 2.5rem;
  margin: 0;
}
.recipe__steps li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: -0.15rem;
  font-family: var(--display);
  font-weight: 800;
  font-size: 1.5rem;
  line-height: 1.4;
  color: var(--coral);
  font-variant-numeric: tabular-nums;
}
