/* ==========================================================================
   Grove Platform — application styles

   Read this before adding a screen. Every screen in this prototype is built
   from the components below. If a screen needs something that is not here,
   add it here first so every other screen can use it too. That rule is the
   whole reason the portals look like one product.

   Contents
     1.  Base
     2.  Prototype chrome
     3.  Rail
     4.  Page — container, breadcrumbs, header      <- the layout contract
     5.  Cards and grids                            <- equal heights live here
     6.  Toolbar — tabs + search + filters, one row
     7.  Stats
     8.  Tables
     9.  Lists and rows
     10. Key/value detail
     11. Pills, dots, meters
     12. Buttons
     13. Forms
     14. Notices
     15. Steps
     16. Empty, toast, misc
   ========================================================================== */

/* 1. Base ================================================================== */

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

html { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }

body {
  margin: 0;
  background: var(--shell);
  font-family: var(--font);
  font-size: var(--text-base);
  line-height: var(--lh-normal);
  color: var(--ink);
}

h1, h2, h3, h4, p, figure { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }

button, input, select, textarea {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
}

a { color: var(--grove); text-decoration: none; }
a:hover { color: var(--plum); }

::selection { background: var(--grove-tint); }

:focus-visible { outline: none; box-shadow: var(--focus); border-radius: var(--r-sm); }

* { scrollbar-width: thin; scrollbar-color: var(--line) transparent; }
*::-webkit-scrollbar { width: 9px; height: 9px; }
*::-webkit-scrollbar-thumb { background: var(--line); border-radius: var(--r-pill); }
*::-webkit-scrollbar-track { background: transparent; }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}


/* 2. Prototype chrome ====================================================== */

.app {
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--shell);
}

.chrome {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: var(--s-4);
  padding: 0 var(--s-5);
  height: var(--topbar-h);
  background: var(--shell);
  border-bottom: 1px solid var(--shell-line);
  z-index: 60;
}

.chrome__brand {
  font-weight: 700;
  font-size: var(--text-md);
  color: var(--shell-fg);
  letter-spacing: 0.01em;
}

.chrome__tag {
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--shell-fg-dim);
  border: 1px solid var(--shell-line);
  border-radius: var(--r-sm);
  padding: 4px 7px;
}

.chrome__spacer { flex: 1; }

.segmented {
  display: flex;
  gap: 3px;
  background: var(--shell-fill);
  border-radius: var(--r-sm);
  padding: 3px;
}

.segmented__btn {
  border: none;
  cursor: pointer;
  border-radius: 6px;
  padding: 6px 13px;
  font-size: var(--text-sm);
  font-weight: 600;
  background: transparent;
  color: var(--shell-fg-dim);
  transition: background var(--speed), color var(--speed);
  white-space: nowrap;
}
.segmented__btn:hover { color: var(--shell-fg); }
.segmented__btn[aria-pressed="true"] { background: var(--shell-fg); color: var(--shell); }

.chrome__role {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding-left: var(--s-4);
  border-left: 1px solid var(--shell-line);
}
.chrome__role-label { font-size: var(--text-xs); font-weight: 500; color: var(--shell-fg-dim); }
.chrome__role select {
  background: var(--shell-fill);
  border: 1px solid var(--shell-line);
  border-radius: var(--r-sm);
  color: var(--shell-fg);
  font-size: var(--text-sm);
  font-weight: 600;
  padding: 6px 9px;
  cursor: pointer;
}

/* The device frame that holds the product itself. */
.frame-wrap {
  flex: 1;
  min-height: 0;
  display: flex;
  justify-content: center;
  padding: var(--s-5);
}

.frame {
  width: 100%;
  max-width: 1600px;
  height: 100%;
  min-height: 0;
  display: flex;
  background: var(--paper);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-frame);
  overflow: hidden;
}

[data-viewport="tablet"] .frame { max-width: 900px; }
[data-viewport="phone"] .frame { max-width: 430px; }


/* 3. Rail ================================================================== */

.rail {
  width: var(--rail-w);
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-right: 1px solid var(--line);
}

.rail__head { padding: var(--s-5) var(--s-5) var(--s-4); }
.rail__logo { height: 42px; width: auto; display: block; }
.rail__hand {
  margin-top: var(--s-3);
  font-family: var(--font-hand);
  font-size: 21px;
  line-height: 1;
  color: var(--plum);
}

.rail__nav {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--s-2) var(--s-3);
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* A flat nav. Spacing separates clusters — no section headings, because a
   heading over a single item ("MONEY → Billing") is noise, not structure. */
.rail__gap { height: var(--s-4); }

.rail__item {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  width: 100%;
  border: none;
  background: transparent;
  cursor: pointer;
  text-align: left;
  padding: 9px var(--s-3);
  border-radius: var(--r-sm);
  font-size: var(--text-base);
  font-weight: 500;
  color: var(--ink-70);
  transition: background var(--speed), color var(--speed);
}
.rail__item:hover { background: var(--paper); color: var(--ink); }
.rail__item[aria-current="page"] {
  background: var(--grove-tint);
  color: var(--ink);
  font-weight: 700;
}
[data-surface="family"] .rail__item[aria-current="page"] { background: var(--plum-tint); }

.rail__item-label { flex: 1; min-width: 0; }

.rail__badge {
  flex-shrink: 0;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: var(--r-pill);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-xs);
  font-weight: 700;
  background: var(--line);
  color: var(--ink-70);
}
.rail__badge--urgent { background: var(--clay-tint); color: var(--clay); }

.rail__foot {
  border-top: 1px solid var(--line);
  padding: var(--s-3);
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.rail__user {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3);
  border-top: 1px solid var(--line);
}
.rail__avatar {
  width: 34px;
  height: 34px;
  border-radius: var(--r-pill);
  background: var(--plum);
  color: #fff;
  display: grid;
  place-items: center;
  font-size: var(--text-sm);
  font-weight: 700;
  flex-shrink: 0;
}
[data-surface="studio"] .rail__avatar { background: var(--grove); }
.rail__user-text { min-width: 0; }
.rail__user-name { display: block; font-size: var(--text-base); font-weight: 700; line-height: 1.25; }
.rail__user-role { display: block; font-size: var(--text-xs); color: var(--ink-45); }


/* 4. Page ==================================================================
   The layout contract. Every screen — list, detail, form, wizard — renders
   inside `.page`. Same width, same gutter, same header shape, every time. */

.scroll {
  flex: 1;
  min-width: 0;
  overflow-y: auto;
  background: var(--paper);
}

.page {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: var(--page-pad-top) var(--page-pad-x) var(--page-pad-bottom);
}

/* Breadcrumbs — present on every screen, so you always know where you are
   and there is always a way back. Replaces the old ad-hoc "‹ Back to X". */
.crumbs {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  min-height: 18px;
  margin-bottom: var(--s-4);
  font-size: var(--text-sm);
  color: var(--ink-45);
}
.crumbs__link {
  border: none;
  background: none;
  padding: 0;
  cursor: pointer;
  font: inherit;
  color: var(--ink-45);
  transition: color var(--speed);
}
.crumbs__link:hover { color: var(--grove); text-decoration: underline; }
/* Sized up from the 12.5px the trail inherits — at that size the chevron
   read as a speck rather than a separator. Kept light so it still sits
   behind the words. */
.crumbs__sep { font-size: 20px; line-height: 1; color: var(--ink-45); opacity: 0.6; }
.crumbs__current { color: var(--ink-70); font-weight: 600; }

/* Page header — a two-column grid so title block and actions share a
   baseline no matter how tall either side gets. */
.page-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: var(--s-5);
  margin-bottom: var(--s-6);
}

.eyebrow {
  font-family: var(--font-hand);
  font-size: 20px;
  line-height: 1;
  color: var(--plum);
  margin-bottom: 6px;
}
[data-surface="studio"] .eyebrow { color: var(--grove); }

.page-title {
  font-size: var(--text-3xl);
  font-weight: 800;
  line-height: var(--lh-tight);
  letter-spacing: -0.015em;
  text-transform: uppercase;
}

.page-sub {
  margin-top: var(--s-2);
  max-width: 62ch;
  font-size: var(--text-md);
  color: var(--ink-70);
  line-height: var(--lh-snug);
}

.page-actions {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  flex-wrap: wrap;
  justify-content: flex-end;
  padding-top: 6px;
}

/* Sections inside a page body. */
.section { margin-top: var(--s-7); }
.section:first-child { margin-top: 0; }

.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
  margin-bottom: var(--s-3);
}
.section-title {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-45);
}


/* 5. Cards and grids =======================================================
   `.grid` stretches its children, `.card` is a full-height flex column.
   Together they guarantee that cards sitting in the same row end level —
   which is the single most visible inconsistency in the old prototype. */

.grid {
  display: grid;
  gap: var(--s-4);
  align-items: stretch;
}
.grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid--sidebar { grid-template-columns: minmax(0, 1.65fr) minmax(0, 1fr); }
.grid--aside { grid-template-columns: minmax(0, 1fr) minmax(0, 1.65fr); }

[data-viewport="tablet"] .grid--3,
[data-viewport="tablet"] .grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* A tablet frame is 900px wide and the rail takes 208 of it, so two columns
   leave about 310px each — too narrow for a table. One column instead. */
[data-viewport="tablet"] .grid--2 { grid-template-columns: minmax(0, 1fr); }
[data-viewport="tablet"] .grid--sidebar,
[data-viewport="tablet"] .grid--aside { grid-template-columns: minmax(0, 1fr); }
[data-viewport="phone"] .grid { grid-template-columns: minmax(0, 1fr) !important; }

/* One grid cell holding two or more stacked cards. Use it when one column of
   a two-column screen is much taller than the other — it balances the pair
   instead of leaving a tall card beside a mostly empty one. */
.grid__col { display: flex; flex-direction: column; gap: var(--s-4); min-width: 0; }
.grid__col > .card { height: auto; }
.grid__col > .card:last-child { flex: 1; }

.card {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-width: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
}

.card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  min-height: 56px;
  padding: var(--s-2) var(--s-5);
  border-bottom: 1px solid var(--line-soft);
}
.card__title {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-45);
}
.card__body { padding: var(--s-5); flex: 1; min-width: 0; }
.card__body--flush { padding: 0; }
/* Lets a single control (usually a textarea) grow to fill the card, so a card
   paired with a taller sibling does not end in dead space. */
.card__body--fill { display: flex; flex-direction: column; }
.field--grow { flex: 1; }
.field--grow .textarea { height: 100%; min-height: 104px; }
.card__note {
  margin-top: auto;
  padding: var(--s-3) var(--s-5) var(--s-4);
  font-size: var(--text-sm);
  color: var(--ink-45);
  line-height: var(--lh-snug);
}
.card__foot {
  margin-top: auto;
  padding: var(--s-3) var(--s-5);
  border-top: 1px solid var(--line-soft);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
}

/* A card that is purely a container for a table — no inner padding. */
.card--table .card__body { padding: 0; }

/* Accent cards, used sparingly for the one thing that matters on a screen. */
.card--grove { background: var(--grove); border-color: var(--grove); color: #fff; }
.card--grove .card__title { color: rgba(255, 255, 255, 0.72); }


/* 6. Toolbar ===============================================================
   Tabs, search, filters and the result count on ONE row. The old prototype
   stacked tabs, then three stat cards, then a search row — three bands of
   mostly-empty space above every table. */

.toolbar {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  flex-wrap: wrap;
  margin-bottom: var(--s-4);
}

.tabs {
  display: flex;
  gap: 2px;
  background: var(--surface-sunk);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 3px;
  flex-shrink: 0;
}
.tabs__btn {
  border: none;
  background: transparent;
  cursor: pointer;
  border-radius: 9px;
  padding: 7px 14px;
  font-size: var(--text-base);
  font-weight: 600;
  color: var(--ink-70);
  white-space: nowrap;
  transition: background var(--speed), color var(--speed);
}
.tabs__btn:hover { color: var(--ink); }
.tabs__btn[aria-selected="true"] {
  background: var(--surface);
  color: var(--ink);
  box-shadow: var(--shadow-card);
}
.tabs__count { color: var(--ink-45); font-weight: 600; }
.tabs__btn[aria-selected="true"] .tabs__count { color: var(--grove); }

.search {
  position: relative;
  flex: 1 1 200px;
  min-width: 160px;
  max-width: 320px;
}
.search__input {
  width: 100%;
  height: 38px;
  padding: 0 var(--s-3) 0 34px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  font-size: var(--text-base);
  transition: border-color var(--speed), box-shadow var(--speed);
}
.search__input::placeholder { color: var(--ink-45); }
.search__input:focus { border-color: var(--grove); box-shadow: var(--focus); outline: none; }
.search__icon {
  position: absolute;
  left: 11px;
  top: 50%;
  transform: translateY(-50%);
  width: 15px;
  height: 15px;
  color: var(--ink-45);
  pointer-events: none;
}

.chips { display: flex; gap: 6px; flex-wrap: wrap; }
.chip {
  border: 1px solid var(--line);
  background: var(--surface);
  cursor: pointer;
  border-radius: var(--r-pill);
  padding: 7px 14px;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink-70);
  white-space: nowrap;
  transition: background var(--speed), border-color var(--speed), color var(--speed);
}
.chip:hover { border-color: var(--ink-45); color: var(--ink); }
.chip[aria-pressed="true"] {
  background: var(--grove-tint);
  border-color: var(--grove-tint-deep);
  color: var(--grove);
}

.toolbar__spacer { flex: 1 1 auto; }
.toolbar__count {
  font-size: var(--text-sm);
  color: var(--ink-45);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}


/* 7. Stats =================================================================
   A slim strip, not a row of oversized cards. Numbers a studio owner glances
   at should not each occupy 120px of vertical space. */

.statbar {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  overflow: hidden;
  margin-bottom: var(--s-4);
}
[data-viewport="phone"] .statbar { grid-auto-flow: row; }

.stat {
  padding: var(--s-4) var(--s-5);
  border-left: 1px solid var(--line-soft);
  min-width: 0;
}
.stat:first-child { border-left: none; }
[data-viewport="phone"] .stat { border-left: none; border-top: 1px solid var(--line-soft); }
[data-viewport="phone"] .stat:first-child { border-top: none; }

.stat__label {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-45);
}
.stat__value {
  margin-top: 3px;
  font-size: var(--text-xl);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}
.stat__value--grove { color: var(--grove); }
.stat__value--plum { color: var(--plum); }
.stat__value--clay { color: var(--clay); }
.stat__sub { margin-top: 2px; font-size: var(--text-sm); color: var(--ink-45); }


/* 8. Tables ================================================================ */

.table-wrap { width: 100%; overflow-x: auto; }

.table { width: 100%; border-collapse: collapse; }

.table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--surface-sunk);
  text-align: left;
  padding: var(--s-3) var(--s-5);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-45);
  white-space: nowrap;
  border-bottom: 1px solid var(--line);
}

.table tbody td {
  padding: var(--s-4) var(--s-5);
  border-bottom: 1px solid var(--line-soft);
  vertical-align: middle;
}
.table tbody tr:last-child td { border-bottom: none; }

.table tbody tr.is-clickable { cursor: pointer; transition: background var(--speed); }
.table tbody tr.is-clickable:hover { background: var(--paper); }

.table .num { text-align: right; font-variant-numeric: tabular-nums; }
.table .shrink { width: 1%; white-space: nowrap; }

.cell-strong { font-weight: 700; }
.cell-sub { font-size: var(--text-sm); color: var(--ink-45); margin-top: 1px; }
.cell-mute { color: var(--ink-70); }


/* 9. Lists and rows ======================================================== */

.rows { display: flex; flex-direction: column; }
.row {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-4) var(--s-5);
  border-bottom: 1px solid var(--line-soft);
}
.row:last-child { border-bottom: none; }
.row--link { cursor: pointer; transition: background var(--speed); border: none; background: none; width: 100%; text-align: left; font: inherit; }
.row--link:hover { background: var(--paper); }

.row__lead { flex-shrink: 0; font-variant-numeric: tabular-nums; color: var(--ink-70); min-width: 52px; }
.row__main { flex: 1; min-width: 0; }
.row__title { font-weight: 700; }
.row__sub { font-size: var(--text-sm); color: var(--ink-45); margin-top: 1px; }
.row__end { flex-shrink: 0; text-align: right; }

/* A time chip, used on Today and Schedule screens. */
.timechip {
  flex-shrink: 0;
  width: 66px;
  border-radius: var(--r-md);
  padding: var(--s-2) 0;
  text-align: center;
  background: var(--grove-tint);
  color: var(--grove);
}
.timechip__h { font-size: var(--text-md); font-weight: 800; line-height: 1.1; }
.timechip__m { font-size: 10px; font-weight: 700; letter-spacing: 0.08em; opacity: 0.75; }
.timechip--plum { background: var(--plum-tint); color: var(--plum); }
.timechip--amber { background: var(--amber-tint); color: var(--amber); }


/* 10. Key/value detail ===================================================== */

.kv { display: flex; flex-direction: column; }
.kv__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
  padding: 9px 0;
  border-bottom: 1px solid var(--line-soft);
}
.kv__row:last-child { border-bottom: none; }
.kv__k { color: var(--ink-70); flex-shrink: 0; }
.kv__v { font-weight: 600; text-align: right; min-width: 0; }
.kv__v--clay { color: var(--clay); }
.kv__v--grove { color: var(--grove); }
.kv__v--mute { font-weight: 400; color: var(--ink-45); }


/* 11. Pills, dots, meters ================================================== */

.pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border-radius: var(--r-pill);
  padding: 4px 11px;
  font-size: var(--text-sm);
  font-weight: 700;
  white-space: nowrap;
  background: var(--line);
  color: var(--ink-70);
}
.pill--ok { background: var(--grove-tint); color: var(--grove); }
.pill--warn { background: var(--plum-tint); color: var(--plum); }
.pill--bad { background: var(--clay-tint); color: var(--clay); }
.pill--amber { background: var(--amber-tint); color: var(--amber); }

.dot {
  width: 8px;
  height: 8px;
  border-radius: var(--r-pill);
  flex-shrink: 0;
  display: inline-block;
  vertical-align: 1px;
  margin-right: 2px;
  background: var(--ink-45);
}

.meter {
  height: 6px;
  border-radius: var(--r-pill);
  background: var(--line);
  overflow: hidden;
}
.meter__fill { height: 100%; border-radius: var(--r-pill); background: var(--grove); }
.meter__fill--full { background: var(--amber); }
.meter__fill--over { background: var(--clay); }


/* 12. Buttons ============================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  height: 38px;
  padding: 0 var(--s-4);
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  font-size: var(--text-base);
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--speed), border-color var(--speed), color var(--speed);
}
.btn:hover { border-color: var(--ink-45); }

.btn--primary { background: var(--grove); border-color: var(--grove); color: #fff; }
.btn--primary:hover { background: var(--grove-ink); border-color: var(--grove-ink); }

.btn--plum { background: var(--plum); border-color: var(--plum); color: #fff; }
.btn--plum:hover { background: var(--plum-ink); border-color: var(--plum-ink); }

.btn--danger { color: var(--clay); }
.btn--danger:hover { border-color: var(--clay); background: var(--clay-tint); }

.btn--quiet { background: transparent; border-color: transparent; color: var(--grove); padding: 0 var(--s-2); }
.btn--quiet:hover { background: var(--grove-tint); border-color: transparent; }

.btn--sm { height: 32px; padding: 0 var(--s-3); font-size: var(--text-sm); }
.btn--lg { height: 46px; padding: 0 var(--s-6); font-size: var(--text-md); }
.btn--block { width: 100%; }

.btn-group { display: flex; gap: var(--s-2); flex-wrap: wrap; }


/* 13. Forms ================================================================
   Form screens use `.grid` like everything else, so their cards stretch to
   equal heights instead of leaving one column short. */

.fields { display: grid; gap: var(--s-4); }
.fields--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
[data-viewport="phone"] .fields--2 { grid-template-columns: minmax(0, 1fr); }

.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field--span { grid-column: 1 / -1; }

.label { font-size: var(--text-base); font-weight: 600; }
.hint { font-size: var(--text-sm); color: var(--ink-45); line-height: var(--lh-snug); }

.input,
.select,
.textarea {
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 0 var(--s-3);
  height: 40px;
  font-size: var(--text-base);
  transition: border-color var(--speed), box-shadow var(--speed);
}
.textarea { height: auto; min-height: 104px; padding: 10px var(--s-3); resize: vertical; line-height: var(--lh-snug); }
.input::placeholder, .textarea::placeholder { color: var(--ink-45); }
.input:focus, .select:focus, .textarea:focus { border-color: var(--grove); box-shadow: var(--focus); outline: none; }

.select {
  appearance: none;
  cursor: pointer;
  padding-right: var(--s-7);
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%238A837A' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--s-3) center;
}

.dropzone {
  border: 1.5px dashed var(--line);
  border-radius: var(--r-md);
  background: var(--paper);
  padding: var(--s-6);
  text-align: center;
  cursor: pointer;
  transition: border-color var(--speed), background var(--speed);
}
.dropzone:hover { border-color: var(--grove); background: var(--grove-tint); }
.dropzone__title { font-weight: 600; }
.dropzone__hint { margin-top: 3px; font-size: var(--text-sm); color: var(--ink-45); }

/* Choice tiles — the radio/checkbox pattern used across registration. */
.choices { display: grid; gap: var(--s-2); }
.choices--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.choices--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
[data-viewport="phone"] .choices { grid-template-columns: minmax(0, 1fr) !important; }

.choice {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  text-align: left;
  width: 100%;
  border: 1px solid var(--line);
  background: var(--surface);
  border-radius: var(--r-md);
  padding: var(--s-3) var(--s-4);
  cursor: pointer;
  font: inherit;
  transition: border-color var(--speed), background var(--speed);
}
.choice:hover { border-color: var(--ink-45); }
.choice[aria-pressed="true"] { border-color: var(--grove); background: var(--grove-tint); }
.choice__mark {
  width: 18px; height: 18px; flex-shrink: 0; margin-top: 1px;
  border: 1.5px solid var(--line); border-radius: 6px; background: var(--surface);
  display: grid; place-items: center;
}
.choice[aria-pressed="true"] .choice__mark { border-color: var(--grove); background: var(--grove); }
.choice__mark svg { opacity: 0; }
.choice[aria-pressed="true"] .choice__mark svg { opacity: 1; }
.choice__body { flex: 1; min-width: 0; }
.choice__title { font-weight: 600; }
.choice__sub { font-size: var(--text-sm); color: var(--ink-45); margin-top: 1px; }
.choice__price { flex-shrink: 0; font-weight: 700; }

/* Toggle */
.toggle {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-4); padding: 11px 0; border-bottom: 1px solid var(--line-soft);
}
.toggle:last-child { border-bottom: none; }
.toggle__body { min-width: 0; }
.toggle__title { font-weight: 600; }
.toggle__sub { font-size: var(--text-sm); color: var(--ink-45); margin-top: 1px; line-height: var(--lh-snug); }
.switch {
  flex-shrink: 0; width: 42px; height: 24px; border-radius: var(--r-pill);
  border: none; background: var(--line); cursor: pointer; padding: 3px;
  display: flex; transition: background var(--speed);
}
.switch__knob {
  width: 18px; height: 18px; border-radius: var(--r-pill);
  background: var(--surface); box-shadow: var(--shadow-card);
  transition: transform var(--speed);
}
.switch[aria-pressed="true"] { background: var(--grove); }
.switch[aria-pressed="true"] .switch__knob { transform: translateX(18px); }

/* The action bar at the foot of every form. Always left-aligned, always the
   same order: primary, then cancel. */
.form-actions {
  display: flex;
  gap: var(--s-2);
  margin-top: var(--s-6);
  padding-top: var(--s-5);
  border-top: 1px solid var(--line);
}


/* 14. Notices ============================================================== */

.notice {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-4) var(--s-5);
  border-radius: var(--r-md);
  border-left: 3px solid var(--ink-45);
  background: var(--surface);
  border-top: 1px solid var(--line);
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.notice + .notice { margin-top: var(--s-3); }
.notice__body { flex: 1; min-width: 0; }
.notice__title { font-weight: 700; }
.notice__text { font-size: var(--text-base); color: var(--ink-70); margin-top: 2px; line-height: var(--lh-snug); }

.notice--bad { background: var(--clay-tint); border-color: var(--clay); border-left-color: var(--clay); }
.notice--bad .notice__text { color: var(--clay); }
.notice--warn { background: var(--plum-tint); border-color: var(--plum-tint); border-left-color: var(--plum); }
.notice--ok { background: var(--grove-tint); border-color: var(--grove-tint); border-left-color: var(--grove); }


/* 15. Steps ================================================================ */

.steps { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; margin-bottom: var(--s-6); }
.step { display: flex; align-items: center; gap: var(--s-2); font-size: var(--text-sm); color: var(--ink-45); }
.step__num {
  width: 22px; height: 22px; border-radius: var(--r-pill);
  display: grid; place-items: center;
  background: var(--line); color: var(--ink-70);
  font-size: var(--text-xs); font-weight: 700;
}
.step[aria-current="step"] { color: var(--ink); font-weight: 700; }
.step[aria-current="step"] .step__num { background: var(--grove); color: #fff; }
.step--done .step__num { background: var(--grove-tint); color: var(--grove); }
.step__arrow { color: var(--line); }


/* 16. Empty, toast, misc =================================================== */

.empty {
  padding: var(--s-9) var(--s-5);
  text-align: center;
  color: var(--ink-45);
}
.empty__title { font-weight: 700; color: var(--ink-70); }
.empty__text { margin-top: 4px; font-size: var(--text-base); }

.toast {
  position: fixed;
  left: 50%;
  bottom: var(--s-7);
  transform: translateX(-50%);
  background: var(--ink);
  color: var(--paper);
  padding: 11px var(--s-5);
  border-radius: var(--r-pill);
  font-size: var(--text-base);
  font-weight: 600;
  box-shadow: var(--shadow-pop);
  z-index: 200;
  pointer-events: none;
}

/* The status pills that sit between a record's header and its cards. */
.flags { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; margin-bottom: var(--s-5); }
/* A rule inside a card separating two kinds of content. */
.card-split { margin-top: var(--s-4); padding-top: var(--s-4); border-top: 1px solid var(--line-soft); }

.stack { display: flex; flex-direction: column; gap: var(--s-4); }
.stack--sm { gap: var(--s-2); }
.stack--lg { gap: var(--s-6); }
.inline { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; }
.spread { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); }
.mute { color: var(--ink-45); }
.strong { font-weight: 700; }
.num { font-variant-numeric: tabular-nums; }
.clay { color: var(--clay); }
.grove { color: var(--grove); }


/* 17. Chat ==================================================================
   A real conversation pane rather than a long document. The message list is
   the only thing that scrolls; the header and the composer stay put, so a
   parent never scrolls past the whole history to answer.

   Used by the family portal's one studio conversation and by the console's
   per-family thread. Both get the same shape; only the outgoing bubble takes
   the surface's accent. */

/* The page opts out of document scrolling so the chat can own the height. */
.scroll--chat { overflow: hidden; }
.page--chat {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
  padding-bottom: var(--s-6);
}
.page--chat .page-head { margin-bottom: var(--s-4); }
.page--chat .page-body { flex: 1; min-height: 0; display: flex; flex-direction: column; }

.chat {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}

.chat__head {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  border-bottom: 1px solid var(--line);
  background: var(--surface);
}
.chat__avatar {
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border-radius: var(--r-pill);
  background: var(--grove);
  color: #fff;
  display: grid;
  place-items: center;
  font-size: var(--text-sm);
  font-weight: 700;
}
[data-surface="family"] .chat__avatar { background: var(--plum); }
.chat__who { flex: 1; min-width: 0; }
.chat__name { display: block; font-weight: 700; line-height: 1.25; }
.chat__status { display: block; font-size: var(--text-sm); color: var(--ink-45); }

/* The only scrolling region on the screen. */
.chat__body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--s-5) var(--s-5) var(--s-4);
  background-color: var(--paper);
  background-image: radial-gradient(circle at 1px 1px, rgba(36, 31, 27, 0.05) 1px, transparent 0);
  background-size: 22px 22px;
}

.chat__day { display: flex; justify-content: center; margin: var(--s-4) 0 var(--s-3); }
.chat__day:first-child { margin-top: 0; }
.chat__day span {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  padding: 3px 12px;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-45);
}

.msg { display: flex; margin-bottom: var(--s-2); }
.msg--out { justify-content: flex-end; }
/* Consecutive messages from the same side sit closer together. */
.msg + .msg { margin-top: 2px; }

.bubble {
  position: relative;
  max-width: 72%;
  min-width: 0;
  padding: 9px 13px 7px;
  border-radius: 14px;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  box-shadow: var(--shadow-card);
}
.msg--in .bubble { border-top-left-radius: 4px; }
.msg--out .bubble {
  background: var(--grove-tint);
  border-color: var(--grove-tint-deep);
  border-top-right-radius: 4px;
}
[data-surface="family"] .msg--out .bubble {
  background: var(--plum-tint);
  border-color: var(--plum-tint);
}

.bubble__who {
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--grove);
  margin-bottom: 2px;
}
[data-surface="family"] .bubble__who { color: var(--plum); }
.bubble__text { line-height: var(--lh-snug); overflow-wrap: anywhere; }
.bubble__time {
  margin-top: 3px;
  text-align: right;
  font-size: 10.5px;
  color: var(--ink-45);
  font-variant-numeric: tabular-nums;
}

/* A studio-wide notice, which is not addressed to this family in particular. */
.bubble--notice { background: var(--amber-tint); border-color: var(--amber-tint); }
.bubble--notice .bubble__who { color: var(--amber); }

.chat__foot {
  flex-shrink: 0;
  display: flex;
  align-items: flex-end;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-4);
  border-top: 1px solid var(--line);
  background: var(--surface);
}
.composer {
  flex: 1;
  min-width: 0;
  min-height: 42px;
  max-height: 132px;
  padding: 11px var(--s-4);
  border: 1px solid var(--line);
  border-radius: 21px;
  background: var(--paper);
  resize: none;
  line-height: var(--lh-snug);
  transition: border-color var(--speed), box-shadow var(--speed);
}
.composer::placeholder { color: var(--ink-45); }
.composer:focus { border-color: var(--grove); box-shadow: var(--focus); outline: none; }
[data-surface="family"] .composer:focus { border-color: var(--plum); }

.chat__send {
  flex-shrink: 0;
  width: 42px;
  height: 42px;
  border: none;
  border-radius: var(--r-pill);
  background: var(--grove);
  color: #fff;
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: background var(--speed);
}
.chat__send:hover { background: var(--grove-ink); }
[data-surface="family"] .chat__send { background: var(--plum); }
[data-surface="family"] .chat__send:hover { background: var(--plum-ink); }


[data-viewport="phone"] .bubble { max-width: 85%; }
[data-viewport="phone"] .chat__body { padding: var(--s-4) var(--s-3); }

/* A conversation with context beside it. The console needs the family's
   details while answering; the parent portal does not, so it uses .chat bare.
   Each column scrolls on its own. */
.chat-layout {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1.9fr) minmax(0, 1fr);
  gap: var(--s-4);
}
.chat-layout__aside {
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
}
.chat-layout__aside > .card { height: auto; flex-shrink: 0; }

/* Narrow viewports give the whole width to the conversation. The family
   record is one tap away from the header action, so nothing is lost. */
[data-viewport="tablet"] .chat-layout,
[data-viewport="phone"] .chat-layout { grid-template-columns: minmax(0, 1fr); }
[data-viewport="tablet"] .chat-layout__aside,
[data-viewport="phone"] .chat-layout__aside { display: none; }

/* Phone: the 244px rail does not fit a 430px frame, so navigation moves to a
   scrollable bar under the content. Desktop and tablet keep the rail. */
.tabbar { display: none; }
[data-viewport="phone"] .rail { display: none; }
[data-viewport="phone"] .frame { flex-direction: column; }
[data-viewport="phone"] .tabbar {
  display: flex;
  flex-shrink: 0;
  gap: 2px;
  padding: 6px;
  overflow-x: auto;
  border-top: 1px solid var(--line);
  background: var(--surface);
}
.tabbar__item {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border: none;
  background: transparent;
  cursor: pointer;
  padding: 9px var(--s-3);
  border-radius: var(--r-sm);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink-70);
  white-space: nowrap;
}
.tabbar__item[aria-current="page"] { background: var(--grove-tint); color: var(--ink); }
[data-surface="family"] .tabbar__item[aria-current="page"] { background: var(--plum-tint); }
.tabbar__badge {
  min-width: 17px;
  padding: 0 5px;
  border-radius: var(--r-pill);
  background: var(--line);
  font-size: 10.5px;
  font-weight: 700;
}

/* On a phone the conversation should start near the top. The subtitle is
   context a parent reads once, so it gives way to the messages. */
[data-viewport="phone"] .page--chat .page-sub { display: none; }
[data-viewport="phone"] .page--chat .page-head { margin-bottom: var(--s-3); }

/* A form's primary action, pinned to the bottom of the viewport while the
   page scrolls under it. On a long screen the button was landing below the
   fold, under an explainer, where people simply did not find it. */
.form-actions--sticky {
  position: sticky;
  bottom: 0;
  z-index: 5;
  margin-top: var(--s-6);
  padding: var(--s-4) 0;
  background: var(--paper);
  border-top: 1px solid var(--line);
  box-shadow: 0 -10px 18px -12px rgba(36, 31, 27, 0.18);
}
.form-actions__hint {
  margin-left: auto;
  align-self: center;
  font-size: var(--text-sm);
  color: var(--ink-45);
  text-align: right;
}

/* A choice big enough to be an obvious tap target for someone who is not
   confident with a screen. */
.choice--lg { padding: var(--s-4) var(--s-5); }
.choice--lg .choice__title { font-size: var(--text-md); }
.choice--lg .choice__mark { width: 22px; height: 22px; }

/* A pill that can be switched on and off — used to attach or detach a policy
   clause from a programme. Off reads as available, not as an error. */
.pill-toggle {
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink-45);
  cursor: pointer;
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 700;
  border-radius: var(--r-pill);
  padding: 5px 12px 5px 9px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: background var(--speed), border-color var(--speed), color var(--speed);
}
.pill-toggle:hover { border-color: var(--ink-45); color: var(--ink-70); }
.pill-toggle__mark {
  width: 15px; height: 15px; flex-shrink: 0;
  border: 1.5px solid var(--line); border-radius: 5px; background: var(--surface);
  display: grid; place-items: center;
}
.pill-toggle__mark svg { opacity: 0; }
.pill-toggle[aria-pressed="true"] {
  background: var(--grove-tint);
  border-color: var(--grove-tint-deep);
  color: var(--grove);
}
.pill-toggle[aria-pressed="true"] .pill-toggle__mark {
  border-color: var(--grove); background: var(--grove);
}
.pill-toggle[aria-pressed="true"] .pill-toggle__mark svg { opacity: 1; color: #fff; }

/* Native date and month pickers keep the same box as every other field; the
   browser's own calendar button sits inside it. */
.input[type="date"],
.input[type="month"] { padding-right: var(--s-2); }
.input[type="date"]::-webkit-calendar-picker-indicator,
.input[type="month"]::-webkit-calendar-picker-indicator { cursor: pointer; opacity: 0.55; }
.input[type="date"]:hover::-webkit-calendar-picker-indicator,
.input[type="month"]:hover::-webkit-calendar-picker-indicator { opacity: 1; }
