/* Family Planner design system. The rules behind these tokens live in docs/agents/design-rules.md;
   change them together. Pages use the classes below via src/ui.rs, never ad-hoc styles. */

@font-face {
  font-family: "Bricolage Grotesque";
  src: url("/static/fonts/bricolage-grotesque-ext.woff2") format("woff2");
  font-weight: 200 800;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Bricolage Grotesque";
  src: url("/static/fonts/bricolage-grotesque.woff2") format("woff2");
  font-weight: 200 800;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Atkinson Hyperlegible Next";
  src: url("/static/fonts/atkinson-ext.woff2") format("woff2");
  font-weight: 200 800;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Atkinson Hyperlegible Next";
  src: url("/static/fonts/atkinson.woff2") format("woff2");
  font-weight: 200 800;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---------------------------------------------------------------- tokens */

:root {
  color-scheme: light dark;

  /* Colour: surfaces and text. */
  --paper: #f5f6f2;
  --card: #ffffff;
  --ink: #1c2530;
  --ink-muted: #55606b;
  --line: #dde1da;
  --line-strong: #b4bcb3;

  /* Colour: the app's one brand colour (actions, focus, today) and the one warning colour (overdue). */
  --pine: #1f5d50;
  --pine-ink: #ffffff;
  --pine-wash: #e1eeea;
  --signal: #b53a08;
  --signal-wash: #fbe8de;

  /* Type */
  --font-display: "Bricolage Grotesque", "Atkinson Hyperlegible Next", system-ui, sans-serif;
  --font-body: "Atkinson Hyperlegible Next", system-ui, sans-serif;
  --text-sm: 0.875rem;
  --text-base: 1.0625rem;
  --text-lg: 1.25rem;
  --text-xl: 1.75rem;
  --text-day: 1.875rem;

  /* Space: a 4px-based scale. Use these, never raw values. */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2.5rem;

  /* Shape: controls, panels and pills each have their own radius. */
  --radius-control: 0.625rem;
  --radius-panel: 0.875rem;

  --tap: 3rem;
  --column: 40rem;
  --tabbar-height: 4.25rem;
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper: #12171c;
    --card: #1a2128;
    --ink: #eceee9;
    --ink-muted: #a3adb5;
    --line: #2b343c;
    --line-strong: #4a5560;
    --pine: #79c9b3;
    --pine-ink: #0c1f1a;
    --pine-wash: #1c2e2a;
    --signal: #ff9166;
    --signal-wash: #35211a;
  }
}

/* ---------------------------------------------------------------- base */

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  font: var(--text-base) / 1.5 var(--font-body);
  background: var(--paper);
  color: var(--ink);
}

main {
  flex: 1;
  width: 100%;
  max-width: var(--column);
  margin: 0 auto;
  padding: var(--space-5) max(var(--space-4), env(safe-area-inset-right)) var(--space-6)
    max(var(--space-4), env(safe-area-inset-left));
}
/* Pages without the tab bar (sign-in, errors) keep the same column. */
body:not(:has(.tabbar)) main { padding-bottom: calc(var(--space-6) + env(safe-area-inset-bottom)); }

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.15;
  text-wrap: balance;
}
h1 { font-size: var(--text-xl); margin: 0 0 var(--space-5); letter-spacing: -0.01em; }
h2 { font-size: var(--text-lg); margin: var(--space-6) 0 var(--space-3); }
h3 { font-size: var(--text-base); margin: var(--space-5) 0 var(--space-2); }
p { margin: 0 0 var(--space-3); max-width: 60ch; }
.muted { color: var(--ink-muted); font-size: var(--text-sm); }

a { color: var(--pine); text-underline-offset: 0.2em; }
a, button, input, select, textarea { min-height: var(--tap); }
a { display: inline-flex; align-items: center; }

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

/* ---------------------------------------------------------------- forms and buttons */

label { display: block; margin-bottom: var(--space-3); font-weight: 600; }
input, select, textarea {
  display: block;
  width: 100%;
  margin-top: var(--space-1);
  padding: var(--space-2) var(--space-3);
  font: inherit;
  font-weight: 400;
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-control);
}
/* Checkboxes and radios sit inline with their label text and keep the tap size. */
label:has(> input[type="checkbox"]), label:has(> input[type="radio"]) {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--tap);
  font-weight: 400;
}
input[type="checkbox"], input[type="radio"] {
  flex: none;
  width: 1.5rem;
  min-height: 1.5rem;
  height: 1.5rem;
  margin: 0;
  accent-color: var(--pine);
}
fieldset {
  margin: 0 0 var(--space-3);
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius-panel);
}
legend { padding: 0 var(--space-2); font-weight: 600; }

button, .button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-width: var(--tap);
  padding: var(--space-2) var(--space-4);
  font: inherit;
  font-weight: 600;
  color: var(--pine-ink);
  background: var(--pine);
  border: 1px solid transparent;
  border-radius: var(--radius-control);
  cursor: pointer;
  text-decoration: none;
}
button:active { translate: 0 1px; }
/* One primary action per screen; everything else is quiet or danger. */
button.quiet, .button.quiet {
  color: var(--pine);
  background: transparent;
  border-color: var(--line-strong);
}
button.danger {
  color: var(--signal);
  background: transparent;
  border-color: var(--line-strong);
}
form { margin: 0; }
form.inline { display: inline; }

/* ---------------------------------------------------------------- app shell */

.tabbar {
  position: sticky;
  bottom: 0;
  z-index: 10;
  display: flex;
  background: var(--card);
  border-top: 1px solid var(--line);
  padding: 0 env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
}
.tabbar a {
  flex: 1;
  flex-direction: column;
  justify-content: center;
  gap: 0.125rem;
  min-height: var(--tabbar-height);
  padding: var(--space-2) 0;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--ink-muted);
  text-decoration: none;
}
.tabbar svg { width: 1.5rem; height: 1.5rem; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.tabbar a[aria-current="page"] { color: var(--pine); }
.tabbar a[aria-current="page"] svg { fill: var(--pine-wash); }

@media (min-width: 48rem) {
  /* Wide screens: the same tabs as a top bar. */
  .tabbar { order: -1; position: static; border-top: 0; border-bottom: 1px solid var(--line); justify-content: center; }
  .tabbar a { flex: 0 0 6.5rem; min-height: 3.5rem; }
}

/* ---------------------------------------------------------------- agenda */

.agenda { display: grid; gap: var(--space-5); }
.agenda__month {
  margin: var(--space-2) 0 calc(var(--space-3) * -1);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 700;
}

.day {
  display: grid;
  grid-template-columns: 3.5rem 1fr;
  column-gap: var(--space-3);
  align-items: start;
}
/* The rail is the memorable part: a big date numeral, with today filled in the brand colour. */
.day__rail { display: grid; justify-items: center; line-height: 1; padding-top: var(--space-1); }
.day__num {
  display: grid;
  place-items: center;
  width: 3.25rem;
  height: 3.25rem;
  border-radius: 50%;
  font-family: var(--font-display);
  font-size: var(--text-day);
  font-weight: 700;
}
.day__name { margin-top: var(--space-1); font-size: var(--text-sm); color: var(--ink-muted); }
.day--today .day__num { background: var(--pine); color: var(--pine-ink); }
.day--today .day__name { color: var(--pine); font-weight: 700; }
.day--overdue .day__num { background: var(--signal-wash); color: var(--signal); }
.day--overdue .day__name { color: var(--signal); font-weight: 700; }

.entries { display: grid; gap: var(--space-2); margin: 0; padding: 0; list-style: none; }

/* An entry: a card with a stripe in the colours of the Members it belongs to. */
.entry {
  position: relative;
  display: grid;
  gap: var(--space-1);
  padding: var(--space-3) var(--space-4) var(--space-3) calc(var(--space-4) + 0.375rem);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-panel);
  overflow: hidden;
}
.entry::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 0.375rem;
  background: var(--stripe, transparent);
}
.entry__title { font-weight: 600; overflow-wrap: anywhere; }
.entry__title a { color: inherit; text-decoration: none; }
.entry__title a:hover { text-decoration: underline; }
.entry__meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-3); font-size: var(--text-sm); color: var(--ink-muted); }
.entry--overdue .entry__meta .entry__when { color: var(--signal); font-weight: 700; }
.entry__empty { margin: 0; padding: var(--space-3) 0; color: var(--ink-muted); }

/* A Member as a filled chip: the colour is a swatch, the name is always ink, so any colour stays readable. */
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 0 var(--space-2);
  border-radius: 999px;
  font-size: var(--text-sm);
  color: var(--ink);
  background: color-mix(in srgb, var(--who) 20%, var(--card));
}
.chip::before {
  content: "";
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 50%;
  background: var(--who);
}

/* ---------------------------------------------------------------- list rows */

/* An item is an entry with a tick on the left and an action on the right. */
.item { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); padding-block: var(--space-2); }
.item__body { display: grid; flex: 1; gap: var(--space-1); min-width: 0; }
.item__extra { flex-basis: 100%; }
.item__extra summary { cursor: pointer; display: flex; align-items: center; min-height: var(--tap); color: var(--pine); font-weight: 600; }
.entries--past .entry__title { color: var(--ink-muted); }
.entries + form, #other-list + form { margin-top: var(--space-4); }
.entries + .add { margin-top: var(--space-5); }
.item__lead, .item__trail { display: flex; align-items: center; }
.item--done .entry__title { text-decoration: line-through; color: var(--ink-muted); font-weight: 400; }

.tick {
  display: grid;
  place-items: center;
  width: var(--tap);
  height: var(--tap);
  padding: 0;
  color: transparent;
  background: transparent;
  border: 2px solid var(--line-strong);
  border-radius: 50%;
}
.tick svg { width: 1.5rem; height: 1.5rem; fill: none; stroke: currentColor; stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }
button.tick:hover, button.tick:focus-visible { color: var(--pine); border-color: var(--pine); }
.tick--done { color: var(--pine-ink); background: var(--pine); border-color: var(--pine); }
button.tick--done:hover, button.tick--done:focus-visible { color: var(--pine-ink); }

/* ---------------------------------------------------------------- forms on pages */

/* A form folded behind a button. */
.add { margin: 0 0 var(--space-5); }
.add > summary { list-style: none; }
.add > summary::-webkit-details-marker { display: none; }
.add > summary::before { content: "+"; font-size: 1.375rem; line-height: 1; }
.add[open] > summary::before { content: "2"; }
.add[open] > summary { color: var(--pine); background: transparent; border-color: var(--line-strong); }
.add__body { margin-top: var(--space-4); padding: var(--space-4); background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-panel); }

/* One-field form where the field leads and the button follows. */
.quick { display: flex; gap: var(--space-2); align-items: end; margin-bottom: var(--space-5); }
.quick label { flex: 1; margin: 0; }

.pair { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.picks { display: flex; flex-wrap: wrap; column-gap: var(--space-4); }
.picks label { margin-bottom: 0; }
.actions { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-4); }

/* Hide what the form's current answers make irrelevant. */
form:has(input[name="all_day"]:checked) .times { display: none; }
form:not(:has(option[value="weekdays"]:checked)) .days { display: none; }

.filters { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: 0 0 var(--space-5); }
.pill {
  padding: 0 var(--space-4);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  color: var(--ink);
  text-decoration: none;
  background: var(--card);
}
.pill[aria-current="true"] { color: var(--pine-ink); background: var(--pine); border-color: var(--pine); font-weight: 600; }
button.pill { font-weight: 400; cursor: pointer; }

/* Marks one row out in words, in the brand colour: "Best so far". */
.badge { padding: 0 var(--space-2); border-radius: 999px; font-size: var(--text-sm); font-weight: 600; color: var(--pine-ink); background: var(--pine); }

[role="alert"] { color: var(--signal); font-weight: 600; }
[role="alert"]:empty { display: none; }

/* ---------------------------------------------------------------- family */

.device { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-2) 0; border-top: 1px solid var(--line); }
.device p { margin: 0; font-size: var(--text-sm); }
.swatch { display: block; width: 100%; padding: var(--space-1); }
input[type="color"] { width: 6rem; padding: var(--space-1); }

/* ---------------------------------------------------------------- outside the app */

.brand { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-6); font-family: var(--font-display); font-size: var(--text-lg); font-weight: 700; color: var(--ink); text-decoration: none; }
.brand img { width: 2.5rem; height: 2.5rem; border-radius: var(--radius-control); }

/* ---------------------------------------------------------------- empty state */

.empty {
  padding: var(--space-5) var(--space-4);
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-panel);
  color: var(--ink-muted);
}
.empty strong { display: block; color: var(--ink); font-family: var(--font-display); font-size: var(--text-lg); }

/* ---------------------------------------------------------------- motion */

@media (prefers-reduced-motion: no-preference) {
  button { transition: translate 80ms ease; }
}
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ---------------------------------------------------------------- month view */
.cal {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: var(--space-1);
  margin-bottom: var(--space-5);
}
.cal__head { text-align: center; color: var(--ink-muted); font-size: var(--text-sm); }
.cal__cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  min-height: var(--tap);
  padding: var(--space-1);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-control);
}
.cal__cell--blank { background: none; border-color: transparent; }
.cal__cell--today { background: var(--pine); border-color: var(--pine); color: var(--pine-ink); font-weight: 600; }
.cal__num { font-family: var(--font-display); }
.cal__dots { display: flex; gap: var(--space-1); }
.cal__dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--who, var(--ink-muted));
  box-shadow: 0 0 0 1px var(--card);
}
