/* styles.css — the card, the form, the button, the status line, the
   language picker and the member list. Requires tokens.css. Phone width
   first; no build step. Trimmed from the trip schedule's styles.css (#3). */
*, *::before, *::after { box-sizing: border-box; }

html { font-size: 100%; -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  color: var(--label);
  background: var(--bg-grouped);
  display: flex;
  justify-content: center;
}

h1 { font-size: var(--text-xl); font-weight: var(--weight-semibold); margin: 0 0 var(--space-2); }

a { color: var(--tint); }

/* #72: the sticky bar's height, kept clear when a field or button is scrolled or tabbed to. It is
   scroll-margin on the page's own controls, not scroll-padding on the root: the bar's own
   buttons sit inside that padding, so a tap on Preferences scrolled the page 64px. */
main :is(input, select, textarea, button, a[href], summary, [tabindex]):not(.navbar *) { scroll-margin-top: 4.5rem; }

/* #72: a two-tone ring: the outline is the outer tone, a shadow in the offset gap the inner one,
   so it reads on light, dark and the sign-in photo. */
:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus);
  outline-offset: 2px;
  box-shadow: 0 0 0 2px var(--color-focus-inner);
}
.signin-toggle:focus-visible, .signin-topbar .lang-picker-toggle:focus-visible {
  box-shadow: 0 0 0 2px var(--color-focus-inner), var(--shadow-pill);
}
::placeholder { color: var(--tertiary-label); opacity: 1; }

/* #15: the signed-in shell. Fills the width up to its maximum and is
   centred (the body's own flex centring does the rest); .page-wide widens
   it further for family and news (#81: 46rem, 60rem). #82: forms
   fill the column; running text keeps a readable measure. #45: no card — the page sits on
   --color-bg; only what must stand out (inputs, the picker's list, news
   items, panels) carries its own border. */
main.page {
  width: 100%;
  max-width: var(--page-max);
  margin: 0;
  padding: 0 calc(var(--gutter) + env(safe-area-inset-right)) calc(var(--space-8) + env(safe-area-inset-bottom)) calc(var(--gutter) + env(safe-area-inset-left));
}
main.page-wide { max-width: var(--page-max-wide); }
/* #81: one gutter, applied once (on main): 16px, 20px from 744px. */
@media (min-width: 744px) { :root { --gutter: 20px; } }

/* #82: running text keeps a readable measure; the forms themselves are not capped. */
main.page p { max-width: 70ch; }

/* #15: family.html's grid — the member cards (and News) fill the width;
   every other direct child of <main> spans the full row. #82: 1, 2 from
   744px, 4 from 960px; a 16px gap (so "Coming up" never touches a card); the
   buttons keep their own 44px and only the cards stretch to the row. */
.page-family {
  display: grid;
  grid-template-columns: 1fr;
  align-items: start;
  gap: var(--sp-2);
}
@media (min-width: 744px) { .page-family { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 960px) { .page-family { grid-template-columns: repeat(4, 1fr); } }
.page-family > h1,
.page-family > .sub,
.page-family > .status-line,
.page-family > .navbar,
.page-family > .panel,
.page-family > .members-list,
.page-family > .hub-apps {
  grid-column: 1 / -1;
}

.sub { color: var(--secondary-label); margin: 0 0 var(--space-5); }

.form-row { margin-bottom: var(--space-4); }
.form-row label {
  display: block;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--secondary-label);
  margin-bottom: var(--space-1);
}
/* #82: one field rule — the form rows and the admin row's city and birthday. */
.form-row input, .form-row select, .form-row textarea, .admin-member-city, .admin-member-birthday {
  max-width: 100%;
  min-height: var(--hit);
  font: inherit;
  padding: var(--sp-1) 12px;
  color: var(--label);
  background: var(--bg-cell);
  border: 1px solid var(--system-gray);
  border-radius: var(--r-cell);
}
.form-row textarea { width: 100%; resize: vertical; }
/* #82: a form fills its column, so a form row's text field is the row's width (dates, times and
   files keep their natural width). Outside a form row, #55's classes still size an input to what
   it holds, never wider than its container. */
.form-row :is(input:not([type="date"]):not([type="time"]):not([type="file"]):not([type="checkbox"]):not([type="radio"]), select) { width: 100%; }
.w-short  { width: 20ch; max-width: 100%; }  /* city/place, member id, username, category */
.w-medium { width: 24ch; max-width: 100%; }  /* a person's name, passwords, search */
.w-long   { width: 28ch; max-width: 100%; }  /* a News topic, muted topic, source domain */
.w-xlong  { width: 32ch; max-width: 100%; }  /* a document name, tags */
.w-xxlong { width: 36ch; max-width: 100%; }  /* an event or fact title, a link */
input[type="date"], input[type="time"] { width: auto; max-width: 100%; }

.btn, .btn-primary {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--hit);          /* #82: two heights — 44 here, 50 for .btn-primary */
  padding: 0 var(--sp-2);
  font: inherit;
  font-weight: 500;
  text-decoration: none;
  border-radius: var(--r-cell);
  border: 1px solid var(--system-gray);
  background: var(--bg-cell);
  color: var(--label);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease);
}
.btn::after {
  content: "";
  position: absolute;
  inset: 50% 0 0 50%;
  width: max(100%, var(--hit));
  height: max(100%, var(--hit));
  transform: translate(-50%, -50%);
}
.btn:disabled { opacity: .45; cursor: default; }   /* #72 */
@media (hover: hover) {
  .btn:hover:not(:disabled) { background: var(--bg-cell-pressed); }
}
.btn-primary {
  width: 100%;
  min-height: 50px;
  margin-top: var(--sp-1);
  border-radius: 12px;
  font-weight: 600;
  color: var(--on-tint);
  background: var(--tint-fill);
  border-color: var(--tint-fill);
}
@media (hover: hover) {
  .btn-primary:hover:not(:disabled) { background: var(--tint); }
}
.btn[hidden] { display: none; }
/* #82: the one compact in-row button (was copied per row): 44px, the smaller type, one line. */
.admin-new-password-btn, .admin-passkey-revoke-btn, .admin-city-save-btn, .admin-birthday-save-btn,
.admin-finance-remove-btn, .news-item-more {
  font: var(--subheadline);
  font-weight: 500;
  padding: 0 12px;
  white-space: nowrap;
}
.admin-new-password-btn, .admin-passkey-revoke-btn, .admin-finance-remove-btn { margin-left: auto; }

.status-line {
  min-height: 1.4em;
  margin: 12px 0 0;
  font: var(--subheadline);
}
.status-line:empty { margin: 0; }
.status-line.is-error { color: var(--destructive); }
.status-line.is-success { color: var(--success-text); }
/* #82: every secondary line is Subheadline (15px) in --secondary-label; 13px is only for group
   headers and footers. */
.notice, .member-city, .member-time, .member-weather, .upcoming-item-sub, .admin-member-state,
.admin-member-passkey, .admin-field-label, .admin-passkey-date, .once-box-note, .news-item-meta,
.document-meta, .calendar-item-when, .calendar-item-place, .calendar-item-by, .facts-item-by,
.facts-item-edited-by {
  font: var(--subheadline);
  color: var(--secondary-label);
}

/* #16: the language picker — one compact button, the same on every page,
   opening a small list of the four. */
.lang-picker-slot { display: flex; justify-content: flex-end; margin-bottom: var(--space-3); }
.lang-picker-widget { position: relative; display: inline-block; }
.lang-picker-toggle { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; min-width: 44px; min-height: 44px; padding: 0; }
/* #45: the flags (img/flags/*.svg, 3:2), a hairline so white Poland shows. */
.lang-flag {
  display: block;
  width: 30px;
  height: 20px;
  border-radius: 2px;
  box-shadow: 0 0 0 1px var(--separator-opaque);
}
/* #81: the navigation bar. Sticky, --row-h tall, translucent --bg-bar with a blur; the hairline
   shows only while collapsed (FamilyUI.navbar toggles .is-collapsed as the large title leaves).
   Back link left, the small title centred, the actions (Preferences, the flag) right. It reaches
   main's gutters at the sides. The picker's open list sits inside it, above everything. */
.navbar {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-1);
  min-height: calc(var(--row-h) + env(safe-area-inset-top));
  padding: env(safe-area-inset-top) var(--gutter) 0;
  margin: 0 calc(-1 * var(--gutter));
  background: var(--bg-bar);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid transparent;
}
.navbar.is-collapsed { border-bottom-color: var(--separator); }
.nav-back, .nav-btn {
  display: inline-flex;
  align-items: center;
  min-height: var(--hit);
  min-width: var(--hit);
  padding: 0;
  border: 0;
  background: none;
  color: var(--tint);
  font: var(--callout);
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
}
.nav-back > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.nav-back { gap: var(--sp-half); margin-left: calc(-1 * var(--sp-half)); }
.nav-btn { justify-content: center; padding: 0 var(--sp-half); }
.nav-title {
  flex: 1 1 0;
  min-width: 0;
  text-align: center;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font: var(--headline);
  color: var(--label);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-fast) var(--ease);
}
.navbar.is-collapsed .nav-title { opacity: 1; }
.nav-actions { display: flex; align-items: center; gap: var(--sp-1); margin-left: auto; flex: 0 0 auto; }
.nav-back { flex: 0 1 auto; min-width: 0; }
.nav-chevron { flex: 0 0 auto; }
.nav-actions > .lang-picker-slot { margin: 0; }
/* news.js puts its "Saved" line after Preferences; ordered before it, the button never moves when the line clears (a tap would miss). */
.nav-actions > #news-prefs-saved { order: -1; }
.large-title { font: var(--large-title); color: var(--label); margin: var(--sp-half) 0 var(--space-3); }
.lang-picker-list {
  position: absolute;
  top: calc(100% + var(--space-2));
  right: 0;
  z-index: 3;
  min-width: 200px;
}
.lang-picker-list[hidden] { display: none; }
.menu {
  display: flex;
  flex-direction: column;
  padding: var(--space-1);
  background: var(--bg-cell);
  border: 1px solid var(--separator-opaque);
  border-radius: var(--r-cell);
  box-shadow: var(--shadow-float);
}
.menu-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: 44px;
  padding: var(--space-1) var(--space-3);
  font: inherit;
  color: var(--label);
  background: transparent;
  border: 0;
  border-radius: calc(var(--r-cell) - 4px);
  text-align: start;
  cursor: pointer;
}
.menu-item:focus-visible { outline: 2px solid var(--tint); outline-offset: -2px; }
.menu-item-label { flex: 1 1 auto; }
.menu-check { flex: 0 0 auto; visibility: hidden; color: var(--tint); }
.menu-item[aria-checked="true"] .menu-check { visibility: visible; }

/* #15, #89: on a phone a sideways scroll-snap row; from 744px unwrapped, so each member card is
   a direct item of .page-family's grid (both in the Hub block at the end). */

/* #27: each member is a card — a round face (or initial), the name, city,
   local time and weather. #82: a cell on the grouped background, not a
   .btn; it stretches to its grid row. */
.member-btn {
  display: flex;
  justify-content: flex-start;
  align-items: flex-start;
  align-self: stretch;
  gap: 12px;
  min-height: var(--hit);
  padding: 12px var(--sp-2);
  text-align: left;
  text-decoration: none;
  color: var(--label);
  background: var(--bg-cell);
  border-radius: var(--r-card);
  transition: background-color var(--dur-fast) var(--ease);
}
@media (hover: hover) {
  .member-btn:hover { background: var(--bg-cell-pressed); }
}
.member-face {
  flex: 0 0 auto;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--on-tint);
  font-weight: 600;
}
.member-face-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.member-info {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.member-name { font-weight: 600; color: var(--label); }
.member-weather { display: flex; align-items: center; gap: var(--space-1); }
.member-weather-icon { font-size: var(--text-md); line-height: 1; }

/* #28: the "Coming up" strip — next birthdays and calendar events. */
.upcoming-panel h2 { margin-top: 0; }
.upcoming-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.upcoming-item {
  display: flex;
  flex-direction: column;
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--separator-opaque);
}
.upcoming-item:last-child { border-bottom: none; padding-bottom: 0; }
.upcoming-item-title { font-weight: var(--weight-medium); }

/* #21, #89: finance.html with no pair lists the member's pairs, one link each. */
.finance-pairs { list-style: none; margin: var(--sp-2) 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-1); }
.finance-pairs[hidden] { display: none; }
.finance-pair-link { justify-content: flex-start; text-align: left; }

.panel {
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: 1px solid var(--separator-opaque);
}
.panel[hidden] { display: none; }
.actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-2); }
.actions .btn-primary { margin-top: 0; }

/* #66: the Preferences sheet's groups: a heading, then the kit's token field. */
.news-prefs-group { margin: 0 0 var(--space-4); }
/* The field's own ring is the input's outline here, so the focused element itself shows focus. */
.news-prefs-group .ui-tokens:focus-within { box-shadow: none; }
.news-prefs-group .ui-token-input { max-width: 36ch; } /* #55: no input wider than 40ch */
.news-prefs-group .ui-token-input:focus-visible { outline: 2px solid var(--tint); outline-offset: 3px; border-radius: 4px; }
.news-prefs-group h3 { margin: 0 0 var(--space-2); font-size: var(--text-base); font-weight: var(--weight-semibold); }

.notice { margin: 0 0 var(--sp-2); }

/* #6 admin: the members list (with state) and the once-box. */
h2 { font-size: var(--text-lg); font-weight: var(--weight-semibold); margin: var(--space-5) 0 var(--space-3); }

/* #82: one grouped list (mapping §2.17). The five row classes are --bg-cell rows on
   --bg-grouped, touching, with an inset --separator hairline between them and --r-cell corners
   on the group; no row has a border of its own. The markup the page scripts build is unchanged. */
.admin-members-list, .admin-finance-pairs-list, .documents-list, .calendar-item-list, .facts-item-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 0;
}
.admin-member-row, .admin-finance-pair-row, .document-item, .calendar-item, .facts-item {
  position: relative;
  padding: 12px var(--sp-2);
  background: var(--bg-cell);
  border: 0;
  border-radius: 0;
}
:is(.admin-member-row, .admin-finance-pair-row, .document-item, .calendar-item, .facts-item):first-child {
  border-top-left-radius: var(--r-cell);
  border-top-right-radius: var(--r-cell);
}
:is(.admin-member-row, .admin-finance-pair-row, .document-item, .calendar-item, .facts-item):last-child {
  border-bottom-left-radius: var(--r-cell);
  border-bottom-right-radius: var(--r-cell);
}
:is(.admin-member-row, .admin-finance-pair-row, .document-item, .calendar-item, .facts-item)
  + :is(.admin-member-row, .admin-finance-pair-row, .document-item, .calendar-item, .facts-item)::before {
  content: "";
  position: absolute;
  top: 0;
  left: var(--sp-2);
  right: 0;
  height: 1px;
  background: var(--separator);
  pointer-events: none;
}
.admin-members-list, .admin-finance-pairs-list { margin: var(--sp-2) 0; }
.admin-finance-pair-row, .admin-member-body {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-half) 12px;
}
.admin-member-name { font-weight: 600; }
/* Amended #56, #68: News is a row of its own (the word, and the switch from
   ui.js); the reset button has the full-width line under it. */
.admin-news-row { flex: 1 1 100%; display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); min-height: 44px; }
.admin-news-row { cursor: pointer; }
.admin-news-row .admin-news-toggle::before { inset: 0; }
.admin-row-actions { flex: 1 1 100%; display: flex; align-items: center; gap: var(--space-2); }
/* #55: each field of a member's row on its own line — the label above,
   then the input with its Save beside it. */
.admin-field { flex: 1 1 100%; }
.admin-field .admin-field-label { display: block; margin-bottom: var(--space-1); }
.admin-field-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-3);
}
/* #27, #28: the admin's per-member city and birthday fields (their look is the field rule
   above); #51: their visible labels are secondary lines. */
.admin-member-city, .admin-member-birthday { flex: 0 1 auto; }
/* #58: a member's passkeys under Birthday — each on its own line: the label,
   then added and last used, and a compact Revoke (the reset's size). */
.admin-passkey-list { list-style: none; margin: 0; padding: 0; }
.admin-passkey-item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-3);
  margin-bottom: var(--space-2);
}
.admin-passkey-name { flex: 1 1 100%; font-weight: var(--weight-medium); overflow-wrap: anywhere; }
/* #68: the once-box is an inset cell on its own line under the row's
   actions: the password in the mono face, Copy on the right with a 44x44 tap
   area, and the "shown once" footnote under the cell. */
.admin-member-row .once-box { flex: 1 1 100%; margin: var(--space-2) 0 0; }
.once-box { margin: var(--space-4) 0; max-width: 100%; }
.once-box[hidden] { display: none; }
.once-box-cell {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: 0 var(--space-1) 0 var(--space-3);
  background: var(--bg-cell);
  border: 1px solid var(--separator-opaque);
  border-radius: 10px;
}
.once-box-password {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 1rem;
  font-weight: var(--weight-semibold);
  min-width: 0;
  overflow-wrap: anywhere;
  word-break: break-all;
}
.once-box-copy {
  flex: 0 0 auto;
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  padding: 0 var(--space-3);
  color: var(--tint);
  background: transparent;
  border: none;
  cursor: pointer;
  white-space: nowrap;
}
.once-box-note { margin: var(--space-1) var(--space-3) 0; }

/* #21: the admin's Finance pairs list — rows of the grouped list above. */
.admin-finance-pair-names { font-weight: 600; flex: 1 1 auto; }

/* #11 News: the edition list and its items. */
.news-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  margin: var(--space-4) 0;
}
.news-edition-heading {
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  margin: 0 0 var(--space-2);
}
.news-item-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  /* #82 (mapping §2.20): equal columns as wide as fit at 18rem — 1 on a phone, 2 in landscape,
     3 at 1440 — each item its own height (an opened story never stretches its row); the
     featured item (news.js sorts it first and marks it `is-featured`) spans 2 from 744px. */
  grid-template-columns: repeat(auto-fill, minmax(min(18rem, 100%), 1fr));
  align-items: start;
  gap: var(--sp-3);
}
@media (min-width: 744px) {
  .news-item-list > .is-featured { grid-column: span 2; }
}
.news-item {
  padding: 0;
}
.news-item-title { font-size: var(--text-base); font-weight: 600; margin: 0 0 var(--space-1); }
.news-item-summary { margin: 0 0 var(--space-2); color: var(--label); }
/* #82: "Source" (News) and "Link" (Calendar) are 44px tall hit boxes. */
.news-item-source, .calendar-item-link { display: inline-flex; align-items: center; min-height: var(--hit); font: var(--subheadline); }
/* #14: the item's small line, its body in place, the stars and the source. */
.news-item-image {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  margin: 0 0 var(--space-2);
  border-radius: var(--r-cell);
  background: var(--bg-cell-pressed);
}
.news-item-image[hidden] { display: none; }
.news-item-meta { margin: 0 0 var(--space-1); }
.news-item-body { margin: var(--space-2) 0 0; }
.news-item-body[hidden] { display: none; }
.news-item-body p { margin: 0 0 var(--space-2); }
.news-item-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-top: var(--space-2);
}
.news-stars { display: flex; gap: 0; }
.news-star {
  min-width: var(--hit);
  min-height: var(--hit);
  padding: 0;
  font: inherit;
  font-size: var(--text-lg);
  line-height: 1;
  background: transparent;
  border: 0;
  border-radius: var(--r-cell);
  color: var(--secondary-label);
  cursor: pointer;
}
.news-star.is-filled { color: var(--label); }
@media (hover: hover) {
  .news-star:hover { background: var(--bg-cell-pressed); }
}

/* #8 sign-in: the family picture full-screen; a small button opens a panel
   beneath it with the form. Scoped to body.sign-in so family.html,
   person.html and admin.html keep the plain body/.card look. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

body.sign-in {
  display: block;
  margin: 0;
  padding: 0;
  min-height: 100vh;
  min-height: 100dvh;
  background-image: url("img/sign-in.jpg");
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

/* #16: the picker sits left of the Sign in button, both on one fixed
   top-right row, so the button's own position (and #8's 80px check) is
   unchanged. */
.signin-topbar {
  position: fixed;
  top: calc(var(--space-3) + env(safe-area-inset-top));
  right: calc(var(--space-3) + env(safe-area-inset-right));
  z-index: 2;
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
}
.signin-topbar > * { flex: 0 0 auto; }
/* #16: the standard --control-h (44px) tap target, not a shorter
   min-height:auto pill — a shorter box leaves .btn::after's own 44px tap
   target poking out past it, which reads as an overflowing box. */
.signin-toggle {
  padding: var(--space-1) var(--space-4);
  border-radius: var(--r-pill);
  box-shadow: var(--shadow-pill);
}
.signin-topbar .lang-picker-toggle {
  border-radius: var(--r-pill);
  box-shadow: var(--shadow-pill);
  background: var(--bg-cell);
}
.signin-topbar .lang-picker-slot { margin-bottom: 0; }

.signin-panel {
  position: fixed;
  top: calc(var(--hit) + var(--space-3) + var(--space-2) + env(safe-area-inset-top));
  left: calc(var(--space-3) + env(safe-area-inset-left));
  right: calc(var(--space-3) + env(safe-area-inset-right));
  z-index: 1;
  background: var(--bg-cell);
  border: 1px solid var(--separator-opaque);
  border-radius: var(--r-card);
  padding: var(--space-6);
  box-shadow: var(--shadow-float);
}
.signin-panel[hidden] { display: none; }
/* #72: the fields and the buttons are one width (the panel's content box). */
.signin-panel input { width: 100%; max-width: 100%; }
/* #82: was index.html's style= on the passkey button. */
.signin-passkey { width: 100%; margin-top: 12px; }

/* #82: a phone's panel spans the width; from 744px it is a 20rem card under the button. */
@media (min-width: 744px) {
  .signin-panel { left: auto; width: 100%; max-width: 20rem; }
}

/* #20 Documents: the Received/Sent tabs, the tag chips, the list and the AI switch. */
.documents-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; }
.documents-head h1 { margin: 0; }
.documents-box { margin: 0 0 var(--space-3); }
.documents-tags { margin: 0 0 var(--space-4); }
.documents-ai-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); font-weight: var(--weight-medium); }
.documents-sheet .form-row { display: flex; flex-direction: column; align-items: stretch; gap: var(--space-1); margin-bottom: var(--space-3); }
.documents-sheet select { width: 100%; max-width: 100%; }
.documents-sheet .ui-tokens input { width: auto; flex: 1 1 8ch; min-width: 8ch; }
/* the kit puts the ring on the field; the input keeps its own thin line so a per-control focus check sees it */
.documents-sheet .ui-token-input { border: 0; background: none; }
.documents-sheet .ui-token-input:focus-visible { box-shadow: none; outline: 2px solid transparent; border-bottom: 1px solid var(--tint); }

/* #67: the facts category pill bar (FamilyUI.pillBar), and the Add/Edit sheets' fields. */
.facts-filter { margin: var(--space-3) 0 var(--space-4); }
.calendar-sheet .form-row, .facts-sheet .form-row { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-1); margin-bottom: var(--space-3); }
.calendar-sheet textarea, .facts-sheet textarea { width: 100%; max-width: 100%; }
.calendar-more { margin: 0 0 var(--space-3); }
.calendar-more > summary { min-height: var(--hit); display: flex; align-items: center; cursor: pointer; font-weight: 500; }
.calendar-more[open] > summary { margin-bottom: var(--space-2); }
.calendar-more > summary::after { content: "\203A"; margin-left: var(--space-2); color: var(--secondary-label); transition: transform 0.2s; }
.calendar-more[open] > summary::after { transform: rotate(90deg); }

.documents-list { margin: 0 0 var(--space-5); }
.document-name { font-size: var(--text-base); font-weight: 600; margin: 0 0 var(--space-1); }
.document-meta { margin: 0 0 var(--space-2); }
.document-tags { display: flex; flex-wrap: wrap; gap: var(--space-1); margin: 0 0 var(--space-2); }
/* #82: a tag is display only — a 28px capsule with no hit area. */
.document-tag {
  display: inline-flex;
  align-items: center;
  height: 28px;
  padding: 0 10px;
  font: var(--subheadline);
  border-radius: var(--r-pill);
  background: var(--fill);
  color: var(--label);
}
.document-summary { margin: 0 0 var(--space-2); }
.document-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.document-edit-form { margin-top: var(--space-3); }
.document-edit-form[hidden] { display: none; }
.document-edit-form .form-row { margin-bottom: var(--space-2); }
.document-status { margin: var(--space-2) 0 0; }

/* #29 Calendar: the month sections and their event rows, the shared Add/Edit form. */
.calendar-month-heading { margin-top: var(--space-6); }
.calendar-month:first-of-type .calendar-month-heading { margin-top: var(--space-5); }

.calendar-item-list { margin: 0 0 var(--space-3); }
.calendar-item-title { font-size: var(--text-base); font-weight: 600; margin: 0 0 var(--space-1); }
.calendar-item-when { margin: 0 0 var(--space-1); }
.calendar-item-place { margin: 0 0 var(--space-2); }
.calendar-item-notes { white-space: pre-line; margin: 0 0 var(--space-2); }
.calendar-item-link { margin: 0 0 var(--space-2); }
.calendar-item-by { margin: 0 0 var(--space-2); }
.calendar-item-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.calendar-item-status { margin: var(--space-2) 0 0; }

/* #30 Family facts: the category sections and their note rows. */
.facts-category-heading { margin-top: var(--space-6); }
.facts-category:first-of-type .facts-category-heading { margin-top: var(--space-5); }

.facts-item-list { margin: 0 0 var(--space-3); }
.facts-item-title { font-size: var(--text-base); font-weight: 600; margin: 0 0 var(--space-1); }
.facts-item-body { white-space: pre-line; margin: 0 0 var(--space-2); }
.facts-item-by, .facts-item-edited-by { margin: 0 0 var(--space-1); }
.facts-item-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.facts-item-status { margin: var(--space-2) 0 0; }

/* ── Apple-style primitives (#64) ─────────────────────────────────────────
   The kit's look (docs/design/apple-kit.html) for site/ui.js's FamilyUI.
   Every class starts with ui-; the new tokens only; one breakpoint, 744px. */
html.ui-locked, html.ui-locked body { overflow: hidden; }

/* Switch: 51×31, green on, inside a row at least 44px tall */
.ui-row { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); min-height: var(--row-h); }
.ui-switch {
  position: relative; flex: none; width: 51px; height: 31px; padding: 0; border: 0; cursor: pointer;
  border-radius: var(--r-pill); background: var(--fill-strong);
  transition: background-color var(--dur) var(--ease);
}
.ui-switch::before { content: ""; position: absolute; inset: -7px -4px; }
.ui-switch::after {
  content: ""; position: absolute; top: 2px; left: 2px; width: 27px; height: 27px; border-radius: 50%;
  background: #fff; box-shadow: var(--shadow-thumb);
  transition: transform var(--dur) var(--spring);
}
/* #82 (owner-approved, mapping §6): the off track carries an inset outline, for 3:1. */
.ui-switch:not([aria-checked="true"]) { box-shadow: inset 0 0 0 1px var(--system-gray); }
.ui-switch:not([aria-checked="true"]):focus-visible { box-shadow: inset 0 0 0 1px var(--system-gray), 0 0 0 2px var(--color-focus-inner); }
.ui-switch[aria-checked="true"] { background: var(--system-green); }
.ui-switch[aria-checked="true"]::after { transform: translateX(20px); }
.ui-switch:disabled { opacity: .4; cursor: default; }
.ui-switch:focus-visible { outline-offset: 3px; }

/* Segmented control: a thumb slides under the checked segment */
.ui-seg {
  position: relative; display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  padding: 2px; border-radius: 9px; background: var(--fill); isolation: isolate; user-select: none;
}
.ui-seg-thumb {
  position: absolute; top: 2px; bottom: 2px; left: 0; z-index: -1; border-radius: 7px;
  background: var(--seg-thumb); box-shadow: var(--shadow-thumb);
  transition: transform var(--dur) var(--ease), width var(--dur) var(--ease);
}
.ui-seg > [role="radio"] {
  position: relative; min-height: 32px; padding: 3px 12px; border: 0; background: none; cursor: pointer;
  font: var(--subheadline); font-weight: 500; color: var(--label); border-radius: 7px; white-space: nowrap;
}
.ui-seg > [role="radio"]::after { content: ""; position: absolute; left: 0; right: 0; top: -6px; bottom: -6px; }
.ui-seg > [role="radio"][aria-checked="true"] { font-weight: 600; }
.ui-seg > [role="radio"]:focus-visible { outline-offset: -2px; }
.ui-seg.ui-no-anim .ui-seg-thumb { transition: none; }
@media (min-width: 744px) { .ui-seg { max-width: 30rem; } }

/* Pill bar: more than four options, scrolls sideways */
.ui-pills {
  display: flex; gap: var(--sp-1); overflow-x: auto; padding: 6px 2px;
  scrollbar-width: none; scroll-snap-type: x proximity;
}
.ui-pills::-webkit-scrollbar { display: none; }
.ui-pills > [role="radio"] {
  flex: none; position: relative; min-height: var(--hit);  /* #82: an interactive pill is 44px */ padding: 6px 16px; border: 0; border-radius: var(--r-pill);
  background: var(--fill); color: var(--label); font: var(--subheadline); font-weight: 500; cursor: pointer;
  scroll-snap-align: center; transition: color var(--dur-fast), background-color var(--dur-fast);
}
.ui-pills > [role="radio"][aria-checked="true"] { background: var(--tint-fill); color: var(--on-tint); font-weight: 600; }
.ui-pills > [role="radio"]:focus-visible { outline-offset: 2px; }

/* Token field: pills whose ✕ is a 44×44 box, and an inline input */
.ui-tokens {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-1);
  min-height: var(--row-h); padding: 6px 12px; border-radius: var(--r-cell); background: var(--bg-cell);
}
.ui-tokens:focus-within { box-shadow: inset 0 0 0 2px var(--tint); }
.ui-token {
  display: inline-flex; align-items: center; max-width: 100%; min-height: 32px; padding-left: 12px;
  border-radius: var(--r-pill); background: var(--fill); color: var(--label); font: var(--subheadline);
}
.ui-token-text { min-width: 0; overflow-wrap: anywhere; padding: 5px 0; }
.ui-token-x {
  position: relative; flex: none; width: var(--hit); height: var(--hit); margin: -6px -4px -6px -6px;
  display: grid; place-items: center; padding: 0; border: 0; background: none; cursor: pointer;
  color: var(--secondary-label); border-radius: var(--r-pill);
}
.ui-token-x svg { width: 18px; height: 18px; }
.ui-token-x:focus-visible { outline-offset: -6px; }
.ui-token-input {
  flex: 1 0 8ch; min-width: 8ch; min-height: 36px; border: 0; padding: 0;
  background: transparent; color: var(--label); font: var(--body);
}
.ui-token-input::placeholder { color: var(--tertiary-label); opacity: 1; }
.ui-token-input:focus-visible { outline: none; }

/* Sheet and action sheet: bottom on a phone, centred from 744px */
.ui-backdrop {
  position: fixed; inset: 0; z-index: 50; background: var(--backdrop);
  opacity: 0; transition: opacity var(--dur) var(--ease);
}
.ui-backdrop.is-open { opacity: 1; }
.ui-backdrop[hidden], .ui-sheet[hidden] { display: none; }
.ui-backdrop-alert { z-index: 60; }
.ui-sheet {
  position: fixed; z-index: 51; left: 0; right: 0; bottom: 0; max-height: calc(100dvh - 44px - env(safe-area-inset-top));
  display: flex; flex-direction: column; background: var(--bg-sheet); color: var(--label);
  border-radius: var(--r-card) var(--r-card) 0 0; box-shadow: var(--shadow-float);
  transform: translateY(100%); transition: transform var(--dur) var(--ease); outline: none;
  padding-bottom: env(safe-area-inset-bottom); font: var(--body);
}
.ui-sheet.is-open { transform: translateY(0); }
.ui-sheet.ui-dragging { transition: none; }
.ui-grabber { flex: none; display: grid; place-items: center; height: 18px; cursor: grab; touch-action: none; }
.ui-grabber::before { content: ""; width: 36px; height: 5px; border-radius: 3px; background: var(--fill-strong); }
.ui-sheet-bar { flex: none; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; padding: 0 var(--sp-1) var(--sp-1); touch-action: none; -webkit-user-select: none; user-select: none; }
.ui-sheet-title { margin: 0; font: var(--headline); color: var(--label); text-align: center; }
.ui-sheet-btn {
  min-height: var(--hit); padding: 0 12px; border: 0; background: none; cursor: pointer;
  color: var(--tint); font: var(--body); border-radius: var(--r-cell);
}
.ui-sheet-cancel { justify-self: start; }
.ui-sheet-save { justify-self: end; font-weight: 600; }
.ui-sheet-btn:disabled { color: var(--tertiary-label); cursor: default; }
.ui-sheet-body { overflow-y: auto; overscroll-behavior: contain; padding: var(--sp-1) var(--sp-2) var(--sp-4); }
.ui-sheet .ui-tokens { background: var(--bg-sheet-cell); }
@media (min-width: 744px) {
  .ui-sheet {
    left: 50%; right: auto; bottom: auto; top: 50%; width: min(34rem, calc(100% - 64px)); max-height: min(720px, calc(100dvh - 96px));
    border-radius: var(--r-card); transform: translate(-50%, -46%) scale(.96); opacity: 0;
    transition: transform var(--dur) var(--ease), opacity var(--dur-fast) linear;
  }
  .ui-sheet.is-open { transform: translate(-50%, -50%); opacity: 1; }
  .ui-grabber { display: none; }
  .ui-sheet-bar { padding-top: var(--sp-1); }
}

.ui-action-sheet {
  position: fixed; z-index: 61; left: var(--sp-1); right: var(--sp-1); bottom: calc(var(--sp-1) + env(safe-area-inset-bottom));
  display: flex; flex-direction: column; gap: var(--sp-1); outline: none;
  transform: translateY(110%); transition: transform var(--dur) var(--ease);
}
.ui-action-sheet.is-open { transform: translateY(0); }
.ui-action-group { display: flex; flex-direction: column; border-radius: var(--r-card); overflow: hidden; background: var(--bg-sheet-cell); }
.ui-action-message { margin: 0; padding: var(--sp-2); text-align: center; font: var(--footnote); color: var(--secondary-label); }
.ui-action {
  min-height: 57px; padding: 0 var(--sp-2); border: 0; cursor: pointer;
  background: var(--bg-sheet-cell); color: var(--tint); font: var(--body); font-size: 1.25rem;
}
.ui-action-group > * + * { border-top: .5px solid var(--separator); }
.ui-action-destructive { color: var(--destructive); }
.ui-action-cancel { border-radius: var(--r-card); font-weight: 600; }
.ui-action:focus-visible { outline-offset: -4px; }
@media (min-width: 744px) {
  .ui-action-sheet {
    left: 50%; right: auto; bottom: auto; top: 50%; width: min(20rem, calc(100% - 64px));
    transform: translate(-50%, -46%) scale(.96); opacity: 0;
    transition: transform var(--dur) var(--ease), opacity var(--dur-fast) linear;
  }
  .ui-action-sheet.is-open { transform: translate(-50%, -50%); opacity: 1; }
}

/* Undo toast: below every modal layer, never over one */
.ui-toast {
  position: fixed; left: 50%; bottom: calc(var(--sp-3) + env(safe-area-inset-bottom));
  z-index: 49;   /* under .ui-backdrop (50): an open sheet or action sheet dims it and takes every tap */
  display: flex; align-items: center; gap: var(--sp-half); max-width: calc(100% - 32px);
  min-height: 50px; padding: 0 6px 0 18px; border-radius: var(--r-pill);
  background: var(--toast-bg); color: var(--toast-text); box-shadow: var(--shadow-float);
  font: var(--subheadline); transform: translateX(-50%);
}
.ui-toast[hidden] { display: none; }
.ui-toast-msg { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ui-toast-undo {
  flex: none; min-height: var(--hit); padding: 0 14px; border: 0; background: none; cursor: pointer;
  color: var(--toast-action); font: var(--subheadline); font-weight: 600; border-radius: var(--r-pill);
}
.ui-toast-undo:focus-visible { outline-color: var(--toast-action); outline-offset: -3px; }

/* Admin (#88): a member row is a <details>: one summary line (name, state, chevron) and the
   controls in its body. The rules for the row's box are #82's grouped list above. */
.admin-member-row { padding-top: 0; padding-bottom: 0; }
.admin-member-summary {
  display: flex; align-items: center; gap: var(--sp-2);
  min-height: 44px; padding: var(--sp-half) 0; box-sizing: border-box; cursor: pointer; list-style: none;
}
.admin-member-row[open] { padding-bottom: 12px; }
.admin-member-summary::-webkit-details-marker { display: none; }
.admin-member-summary:focus-visible { outline-offset: 2px; border-radius: var(--r-cell); }
.admin-member-lines { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; }
.admin-member-lines > * { line-height: 1.3; }
.admin-member-sub { display: flex; flex-wrap: wrap; gap: 0 var(--sp-1); }
.admin-member-chevron { flex: none; display: inline-flex; color: var(--tertiary-label); transition: transform 0.15s; }
.admin-member-row[open] > .admin-member-summary .admin-member-chevron { transform: rotate(90deg); }
.admin-member-body { padding-top: var(--sp-1); }
/* A closed row's controls are out of the layout and the tab order (not merely clipped). */
.admin-member-row:not([open]) > .admin-member-body { display: none; }
.admin-member-body > .admin-row-status { flex: 1 1 100%; margin: 0; }
.admin-birthday-state { font: var(--footnote); color: var(--secondary-label); }
@media (prefers-reduced-motion: reduce) { .admin-member-chevron { transition: none; } }

/* My page (#87) — person.html?id=<me>: inset grouped lists (§2.9), built on the tokens. */
.my-page { margin-top: var(--sp-2); }
.my-group { margin: 0 0 var(--sp-4); }
.my-group-title {
  margin: 0 0 6px; padding: 0 var(--sp-2);
  font: var(--footnote); text-transform: uppercase; letter-spacing: .02em; color: var(--secondary-label);
}
.my-list { margin: 0; padding: 0; list-style: none; background: var(--bg-cell); border-radius: var(--r-cell); overflow: hidden; }
.my-list [hidden] { display: none; }
.my-row {
  position: relative; display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-1) var(--sp-2);
  box-sizing: border-box; width: 100%; min-height: var(--row-h); margin: 0; padding: 11px var(--sp-2);
  font: var(--body); color: var(--label); background: transparent; text-align: start;
}
/* The hairline between rows, inset from the leading edge as iOS draws it. */
.my-list .my-row:not(:first-child)::before, .my-sublist > .my-row::before {
  content: ""; position: absolute; top: 0; left: var(--sp-2); right: 0; height: 1px;
  background: var(--separator); transform: scaleY(.5); transform-origin: top;
}
.my-sublist { margin: 0; padding: 0; list-style: none; }
.my-row-label { flex: 1 1 7rem; min-width: 0; }
.my-row-head { font: var(--headline); }
.my-row-note { font: var(--subheadline); color: var(--secondary-label); }
.my-row-input {
  flex: 1 1 8rem; width: auto; min-width: 0; max-width: 20ch; min-height: 32px; margin: 0; padding: 0 var(--sp-half);
  font: var(--body); color: var(--secondary-label); text-align: end;
  background: transparent; border: 0; border-radius: 6px;
}
.my-row-input:focus { color: var(--label); }
.my-row-input:focus-visible { outline: 2px solid var(--tint); outline-offset: 2px; }
.my-saved { display: inline-flex; align-items: center; gap: var(--sp-half); flex: none; font: var(--subheadline); color: var(--success-text); }
.my-saved[hidden] { display: none; }
.my-row-button { border: 0; border-radius: 0; cursor: pointer; justify-content: space-between; }
.my-row-button:active { background: var(--bg-cell-pressed); }
.my-row-button:focus-visible { outline: 2px solid var(--focus); outline-offset: -3px; }
.my-row-tint { color: var(--tint); }
.my-row-destructive { color: var(--destructive); justify-content: flex-start; }
.my-chevron { flex: none; color: var(--tertiary-label); }
.passkey-row .passkey-label { flex: 1 1 auto; font-weight: 600; }
.passkey-row .passkey-date, .passkey-row .passkey-used { font: var(--subheadline); color: var(--secondary-label); }
.my-footer { margin: 6px 0 0; padding: 0 var(--sp-2); font: var(--footnote); color: var(--secondary-label); }
.my-footer[hidden], .my-status:empty { display: none; }
.my-status.is-error { color: var(--destructive); }
.my-status.is-success { color: var(--success-text); }
.my-sheet-form { margin: 0; }
.my-sheet-form .notice { margin: 0 0 var(--sp-2); }
.my-sheet-form .my-list { background: var(--bg-sheet-cell); }
.my-sheet-form .my-row-label { flex: 0 0 auto; }
.my-sheet-form .my-row-input { flex: 1 1 12ch; }

/* Hub (#89) — family.html: the members, the apps, Coming up, My page, top to bottom. */
/* The members are a sideways scroll-snap row on a phone, in the server's order; from 744px the
   row is unwrapped into .page-family's grid (the phone-only properties then do nothing). */
.members-list {
  display: flex; gap: var(--sp-2); overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; scroll-padding-inline: 4px; padding: 4px; margin: -4px;
  min-width: 0; /* a grid item: without it the row's width widens the page instead of scrolling */
  position: relative; /* the cards' visually-hidden weather words scroll with the row, not the page */
}
.members-list > .member-btn { flex: 0 0 min(16rem, 78%); scroll-snap-align: start; }
@media (min-width: 744px) { .members-list { display: contents; } }
/* The apps: rounded-square icons with the label under them, 4 per row, 6 from 744px. */
.hub-apps { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--sp-2) var(--sp-1); margin: var(--sp-1) 0; }
@media (min-width: 744px) { .hub-apps { grid-template-columns: repeat(6, minmax(0, 1fr)); } }
.app-tile {
  display: flex; flex-direction: column; align-items: center; gap: 6px; min-height: var(--hit);
  color: var(--label); text-decoration: none; text-align: center; font: var(--footnote);
  overflow-wrap: anywhere; border-radius: var(--r-cell);
}
.app-tile[hidden] { display: none; }
.app-icon {
  display: flex; align-items: center; justify-content: center; width: 60px; height: 60px;
  border-radius: var(--r-card); color: var(--on-tint); background: var(--system-gray);
  transition: filter var(--dur-fast) var(--ease);
}
.app-tile:active .app-icon { filter: brightness(.85); }
@media (hover: hover) { .app-tile:hover .app-icon { filter: brightness(.92); } }
.app-icon-news { background: var(--system-red); }
.app-icon-documents { background: var(--system-blue); }
.app-icon-facts { background: var(--system-orange); }
.app-icon-finance { background: var(--system-green); }
.app-icon-calendar { background: var(--bg-cell); color: var(--label); }
.app-icon-calendar .app-cal-weekday { fill: var(--system-red); font-weight: 600; }
.app-icon-calendar .app-cal-day { font-weight: 300; }
/* The empty error line takes no grid row (no band under the title); it stays in the tree, so its
   alert still reads when filled, and returns to its row when it has text. */
.page-family > .status-line:empty { position: absolute; }
/* Coming up is a widget card. */
.page-family > .upcoming-panel {
  margin-top: 0; padding: var(--sp-2); border-top: 0;
  background: var(--bg-cell); border-radius: var(--r-card);
}

/* Member page (#90): another member's person.html, a contact card, their next birthday, Send a document. */
.other-page { margin-top: var(--sp-2); }
.contact-card { margin: 0 0 var(--sp-2); }
.contact-birthday { margin: 0 0 var(--sp-3); padding: 0 var(--sp-2); font: var(--subheadline); color: var(--secondary-label); }
.contact-birthday[hidden] { display: none; }
.other-page .my-list > a.my-row { text-decoration: none; }
.other-page .my-list > a.my-row:active { background: var(--bg-cell-pressed); }
@media (hover: hover) { .contact-card .member-btn:hover { background: var(--bg-cell); } }

/* Forced sheet sign-out (#92) */
.my-sheet-form .forced-sign-out { margin-top: var(--sp-2); }

/* Facts note (#94) */
.facts-note {
  display: flex; align-items: flex-start; gap: var(--sp-1);
  margin: 0 0 var(--sp-2); padding: var(--sp-1) var(--sp-2);
  background: var(--bg-cell); border-radius: var(--r-cell);
  color: var(--secondary-label);
}
.facts-note-icon { flex: none; margin-top: 1px; }
.facts-note-text { margin: 0; font-size: 15px; line-height: 1.35; color: var(--secondary-label); }
