/* Phosphor: a modern family planner, lit the way an old green screen was.

   One stylesheet, and one small script for the box (ask.js) that the page works without. The
   page is a present-day app: calm charcoal surfaces, a friendly sans, line icons, generous
   space. The old monitor survives as light, not as costume: phosphor green glows on the few
   things that deserve it (the name, the button to press, the box you are typing in, what is
   next, what is live, the day's spend) and nowhere else, amber glows for today, and the page's
   few pictures are old green-screen monitors, the one place it is hazy. Each part of the site
   has its own colour, so colour says where you are. docs/STYLE.md says why. */

/* ---- Type ------------------------------------------------------------------------------- */
/* Served from here, because the content policy lets fonts come from this site only. */
@font-face {
  font-family: "DM Sans";
  src: url("fonts/dm-sans.woff2") format("woff2");
  font-weight: 100 1000;
  font-display: swap;
}
@font-face {
  font-family: "DM Mono";
  src: url("fonts/dm-mono-400.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "DM Mono";
  src: url("fonts/dm-mono-500.woff2") format("woff2");
  font-weight: 500 700;
  font-display: swap;
}
/* A terminal's face, the DEC VT320's, for the words on a green screen and nowhere else. */
@font-face {
  font-family: "VT323";
  src: url("fonts/vt323.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}

/* ---- Tokens ----------------------------------------------------------------------------- */
:root {
  color-scheme: dark;

  /* Charcoal with a breath of green in it: the colour of a screen switched off. */
  --bg: #0b0e0d;
  --surface: #121615;
  --surface-2: #171c1a;
  --surface-3: #1d2321;
  --field: #0e1211;
  --line: #232a27;
  --line-2: #2f3834;
  --edge: #5c6862;           /* the edge of anything you type in or press: 3.1:1 on a surface */

  --ink: #edf2ef;
  --ink-2: #bac5bf;          /* secondary words */
  --dim: #919e98;            /* quiet words: 6.6:1 on a surface */
  --faint: #7d8a84;          /* placeholders and ids: 5:1 on a field */

  /* The phosphors of the time, softened: the green and amber of the monitors, and the bright
     cyan, yellow, magenta and red of the first colour screens. Each part of the site takes one.
     Tuned so no two that share a page are easily confused, for typical sight or the commonest
     colour-blindness (docs/STYLE.md has the measures). */
  --green: #6dff9c;          /* the brand, a green screen's phosphor */
  --green-hover: #92ffb8;
  --lilac: #ae9bff;          /* ideas */
  --cyan: #6cd4ff;           /* plans and dates, and going places */
  --lemon: #f7dc78;          /* things to do */
  --amber: #ffb850;          /* people, food, today: an amber screen's phosphor */
  --pink: #ff9fd0;           /* shows, and children's faces */
  --orange: #ff956c;         /* the seasons */
  --red: #ff6b6b;            /* only what went wrong, or cannot be undone */
  --on-bright: #07130c;      /* words on any of the colours above */

  --accent: var(--green);    /* this page's colour; see "Sections" */

  --glow: 0 0 0 1px rgb(109 255 156 / 0.35), 0 8px 28px -10px rgb(109 255 156 / 0.7);
  /* Phosphor persistence: what lights up does so at once, and fades the way a tube's glow did,
     falling fast and lingering a moment. Used for every glow that follows the pointer or focus. */
  --afterglow: 1.2s cubic-bezier(0.2, 0.7, 0.3, 1);
  --glow-in: 0.12s;
  --shadow: inset 0 1px 0 rgb(255 255 255 / 0.035), 0 12px 32px -22px rgb(0 0 0 / 0.9);

  --r-xl: 22px;
  --r-lg: 16px;
  --r: 12px;
  --r-sm: 10px;

  --sans: "DM Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: "DM Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  --terminal: "VT323", "DM Mono", ui-monospace, Menlo, Consolas, monospace;

  --tab-h: 4.25rem;          /* the tab bar on a phone */
}

/* ---- Sections ----------------------------------------------------------------------------- */
/* Each part of the site has a colour: the tile beside its title, its tab, its place in the bar
   and its links take it. The bar's own links carry theirs, so the icon of the current page is
   lit in the colour of that page. */
.in-ideas, .to-ideas { --accent: var(--lilac); }
.in-plans, .to-plans { --accent: var(--cyan); }
.in-todo, .to-todo { --accent: var(--lemon); }
.in-wishes, .to-wishes { --accent: var(--pink); }
.in-family, .to-family { --accent: var(--amber); }
.in-you, .to-you { --accent: var(--amber); }
.in-memory, .to-memory { --accent: var(--amber); }

/* And each kind of idea has one, on its label and when its card is hovered. */
.kind { --kind: var(--lilac); }
.kind-restaurant { --kind: var(--amber); }
.kind-activity { --kind: var(--lemon); }
.kind-outing { --kind: var(--green); }
.kind-day_trip { --kind: var(--cyan); }
.kind-trip { --kind: var(--cyan); }
.kind-show { --kind: var(--pink); }
.kind-seasonal { --kind: var(--orange); }
:is(.card, .idea-card, .idea-main):has(.kind-restaurant) { --accent: var(--amber); }
:is(.card, .idea-card, .idea-main):has(.kind-activity) { --accent: var(--lemon); }
:is(.card, .idea-card, .idea-main):has(.kind-outing) { --accent: var(--green); }
:is(.card, .idea-card, .idea-main):has(.kind-day_trip, .kind-trip) { --accent: var(--cyan); }
:is(.card, .idea-card, .idea-main):has(.kind-show) { --accent: var(--pink); }
:is(.card, .idea-card, .idea-main):has(.kind-seasonal) { --accent: var(--orange); }
:is(.card, .idea-card, .idea-main):has(.kind-event, .kind-other) { --accent: var(--lilac); }

/* ---- The page ----------------------------------------------------------------------------- */
* { box-sizing: border-box; }

/* The faintest afterglow at the top, as if a screen had just been switched off. */
html {
  background:
    radial-gradient(60% 38% at 50% -10%, rgb(109 255 156 / 0.075), transparent 70%),
    var(--bg);
  background-repeat: no-repeat;
  scroll-padding-top: 5.5rem;
  -webkit-text-size-adjust: 100%;
}
body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  color: var(--ink);
  font: 400 1rem/1.6 var(--sans);
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection { color: var(--on-bright); background: var(--green); }
:focus-visible { outline: 2px solid var(--green); outline-offset: 3px; border-radius: 6px; }

a {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
  transition: color 0.15s, text-decoration-color 0.15s;
}
a:hover { text-decoration-color: currentColor; }

p { margin: 0.5rem 0; }
code {
  font: 0.88em var(--mono);
  color: var(--ink-2);
  background: var(--surface-3);
  border-radius: 6px;
  padding: 0.08rem 0.38rem;
}

h1, h2, h3 { text-wrap: balance; }
h1 { margin: 0; font-size: clamp(1.9rem, 4.2vw, 2.6rem); font-weight: 700; line-height: 1.08; letter-spacing: -0.025em; }
h2 { margin: 1.75rem 0 0.75rem; font-size: 1.2rem; font-weight: 650; line-height: 1.3; letter-spacing: -0.015em; }
h3 {
  margin: 1.5rem 0 0.6rem;
  font: 500 0.72rem/1.3 var(--mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--dim);
}

.muted { color: var(--dim); }
.small { font-size: 0.9rem; }
.warn { color: var(--amber); }
.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
[hidden] { display: none !important; }

/* The glow itself, for the few words that get it. */
.glow {
  color: var(--green);
  text-shadow: 0 0 0.45em rgb(109 255 156 / 0.45), 0 0 1.3em rgb(109 255 156 / 0.22);
}

/* ---- Icons ------------------------------------------------------------------------------- */
/* Line icons, drawn with a stroke that takes the colour of the words beside them. */
.icon {
  width: 1.2em;
  height: 1.2em;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: -0.24em;
}
/* Anything that holds an icon beside its words lines them up with a gap, whichever side. */
button, .button, .eyebrow, .section-head a, .tabs a, .links a, .meta > span, .facts dt,
summary, .clear, .today-hours, .reminder, strong.warn, .kind, .foot-mark, .next-where {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
}

/* ---- The bar ------------------------------------------------------------------------------ */
.skip { position: absolute; left: -10000px; }
.skip:focus {
  left: 1rem;
  top: 0.6rem;
  z-index: 50;
  padding: 0.55rem 0.85rem;
  color: var(--on-bright);
  background: var(--green);
  border-radius: var(--r-sm);
}

.bar {
  position: relative;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-height: 3.75rem;
  padding: 0.55rem clamp(1rem, 3vw, 2rem);
  background: rgb(11 14 13 / 0.82);
  border-bottom: 1px solid var(--line);
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  min-width: 0;
  color: var(--ink);
  text-decoration: none;
}
.brand-mark {
  display: grid;
  place-items: center;
  flex: none;
  width: 2.2rem;
  height: 2.2rem;
  color: var(--green);
  background: radial-gradient(circle at 50% 35%, #173022, #0e1512 70%);
  border: 1px solid rgb(109 255 156 / 0.28);
  border-radius: 11px;
  box-shadow: 0 0 22px -6px rgb(109 255 156 / 0.55);
}
.brand-mark .icon { width: 1.3rem; height: 1.3rem; stroke-width: 2; filter: drop-shadow(0 0 3px rgb(109 255 156 / 0.75)); }
.brand-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 500 1.05rem/1 var(--mono); letter-spacing: -0.01em; }
/* The cursor after the name, blinking like a terminal's for a few seconds as the page opens. */
.caret {
  flex: none;
  width: 0.5rem;
  height: 1.05rem;
  margin-left: -0.35rem;
  background: var(--green);
  border-radius: 1px;
  box-shadow: 0 0 10px rgb(109 255 156 / 0.8);
  animation: blink 1.2s steps(1) 8;
}

nav a {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--dim);
  text-decoration: none;
  font: 500 0.92rem/1 var(--sans);
  border-radius: var(--r-sm);
  transition: color 0.15s, background-color 0.15s;
}
nav a .icon { width: 1.25rem; height: 1.25rem; }
nav a:hover { color: var(--ink); background: var(--surface-2); }
nav a[aria-current="page"] { color: var(--ink); background: var(--surface-3); }
nav a[aria-current="page"] .icon { color: var(--accent); filter: drop-shadow(0 0 5px color-mix(in srgb, var(--accent) 70%, transparent)); }

.tools { display: flex; align-items: center; gap: 0.15rem; margin-left: auto; }
.tools > a { padding: 0.6rem; }
.tools .label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* The last tile in the bar opens a menu: the pages of settings, then who is signed in, their
   password and signing out. Its tile looks like the others, with a caret that turns as it opens. */
.menu { position: relative; }
.menu > summary {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.6rem;
  color: var(--dim);
  font: 500 0.92rem/1 var(--sans);
  list-style: none;
  cursor: pointer;
  border-radius: var(--r-sm);
  transition: color 0.15s, background-color 0.15s;
}
.menu > summary::-webkit-details-marker { display: none; }
.menu > summary::before { content: none; }
.menu > summary::after {
  content: "";
  width: 0.36rem;
  height: 0.36rem;
  margin-top: -0.2rem;
  border: solid currentColor;
  border-width: 0 1.5px 1.5px 0;
  transform: rotate(45deg);
  transition: transform 0.15s;
}
.menu[open] > summary::after { margin-top: 0.2rem; transform: rotate(-135deg); }
.menu > summary .icon { width: 1.25rem; height: 1.25rem; }
.menu > summary:hover, .menu[open] > summary { color: var(--ink); background: var(--surface-2); }
.menu.here > summary { color: var(--ink); background: var(--surface-3); }
.menu.here > summary .icon { color: var(--accent); filter: drop-shadow(0 0 5px color-mix(in srgb, var(--accent) 70%, transparent)); }
.menu-list {
  position: absolute;
  top: calc(100% + 0.45rem);
  right: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  width: max-content;
  min-width: 14.5rem;
  max-width: calc(100vw - 2rem);
  max-height: calc(100dvh - 5.5rem);
  overflow-y: auto;
  padding: 0.4rem;
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: var(--r);
  box-shadow: 0 22px 44px -18px rgb(0 0 0 / 0.95);
}
.menu-list a { gap: 0.65rem; padding: 0.6rem 0.7rem; color: var(--ink-2); line-height: 1.3; }
.menu-list a .icon { width: 1.05rem; height: 1.05rem; color: var(--dim); }
.menu-list a[aria-current="page"] { color: var(--ink); background: var(--surface-2); }
.menu-list a[aria-current="page"] .icon { color: var(--accent); filter: none; }
.menu-all { margin-bottom: 0.2rem; padding-bottom: 0.2rem; }
.menu-you { display: flex; flex-direction: column; gap: 0.1rem; }
.menu-list a + .menu-you { margin-top: 0.3rem; padding-top: 0.4rem; border-top: 1px solid var(--line); }
.menu-who { margin: 0.3rem 0.7rem 0.35rem; color: var(--dim); font-size: 0.85rem; }
.menu-who strong { color: var(--ink); font-weight: 600; }
.signout { margin: 0; }
.signout button.quiet {
  justify-content: flex-start;
  gap: 0.65rem;
  width: 100%;
  min-height: 0;
  padding: 0.6rem 0.7rem;
  color: var(--ink-2);
  font: 500 0.92rem/1.3 var(--sans);
  border-color: transparent;
}
.signout button.quiet .icon { width: 1.05rem; height: 1.05rem; color: var(--dim); }
.signout button.quiet:hover { border-color: transparent; }

/* On a phone: the places are tabs along the bottom, where a thumb is, one column each: five,
   or six with the wish lists. */
.places {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 30;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  padding: 0.4rem 0.35rem calc(0.4rem + env(safe-area-inset-bottom));
  background: rgb(14 18 17 / 0.94);
  border-top: 1px solid var(--line);
}
.places a {
  flex-direction: column;
  justify-content: center;
  gap: 0.25rem;
  min-height: 3.35rem;
  padding: 0.3rem 0.1rem;
  font-size: 0.72rem;
  white-space: nowrap;
  background: none;
}
.places a:hover { background: none; }
.places a .icon { width: 1.35rem; height: 1.35rem; padding: 0.28rem 0.8rem; box-sizing: content-box; border-radius: 999px; }
.places a[aria-current="page"] { background: none; }
.places a[aria-current="page"] .icon { background: color-mix(in srgb, var(--accent) 16%, transparent); }
/* Blurred glass behind the tab bar. Not behind the bar at the top on a phone: a filter there
   would become the frame the tab bar is fixed to, and pull it up to the top of the page. */
@supports (backdrop-filter: blur(1px)) {
  .places { backdrop-filter: blur(16px) saturate(1.4); }
}

/* Wider: everything in one bar at the top, which stays put while the page moves. */
@media (min-width: 52rem) {
  .bar { position: sticky; top: 0; gap: 1rem; }
  .places {
    position: static;
    display: flex;
    gap: 0.15rem;
    padding: 0;
    margin-left: 1rem;
    background: none;
    border: 0;
    backdrop-filter: none;
  }
  .places a { flex-direction: row; min-height: 0; padding: 0.55rem 0.8rem; font-size: 0.92rem; }
  .places a .icon, .places a[aria-current="page"] .icon { width: 1.2rem; height: 1.2rem; padding: 0; margin: 0; background: none; }
  .places a[aria-current="page"] { background: var(--surface-3); }
  .places a:hover { background: var(--surface-2); }
  .places a:first-child { display: none; } /* the name at the left goes home already */
  @supports (backdrop-filter: blur(1px)) {
    .bar { backdrop-filter: blur(16px) saturate(1.4); }
  }
}
@media (min-width: 84rem) {
  .tools > a, .menu > summary { padding: 0.55rem 0.8rem; }
  .tools .label { position: static; width: auto; height: auto; overflow: visible; clip-path: none; }
}
@media (max-width: 51.99rem) {
  .foot { padding-bottom: calc(var(--tab-h) + 1.5rem + env(safe-area-inset-bottom)) !important; }
}

/* ---- The frame of a page ------------------------------------------------------------------ */
main {
  flex: 1 0 auto;
  width: 100%;
  max-width: 74rem;
  margin: 0 auto;
  padding: clamp(1.5rem, 4vw, 2.75rem) clamp(1rem, 3vw, 2rem) 4rem;
}

.eyebrow {
  margin: 0;
  font: 500 0.72rem/1.3 var(--mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--dim);
}

.page-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem 1.5rem;
  margin: 0 0 2rem;
}
.page-title { min-width: 0; }
.title-row { display: flex; align-items: center; gap: 0.85rem; }
.title-row h1 { overflow-wrap: anywhere; }
/* The page's icon on a tile of its own colour: the one glow in a page head. */
.title-icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 2.6rem;
  height: 2.6rem;
  color: var(--accent);
  /* A small lit screen: its own faint raster, the icon glowing on it. */
  background:
    repeating-linear-gradient(to bottom, rgb(0 0 0 / 0.22) 0 1px, transparent 1px 3px),
    color-mix(in srgb, var(--accent) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  border-radius: 13px;
  box-shadow: 0 0 26px -8px color-mix(in srgb, var(--accent) 60%, transparent);
}
.title-icon .icon { width: 1.35rem; height: 1.35rem; filter: drop-shadow(0 0 3px color-mix(in srgb, var(--accent) 70%, transparent)); }
.lede { margin: 0.7rem 0 0; max-width: 60ch; color: var(--dim); font-size: 1.05rem; }
.page-actions { display: flex; flex-wrap: wrap; gap: 0.6rem; }

.crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 0.45rem; margin: 0 0 0.9rem; font-size: 0.9rem; color: var(--faint); }
.crumbs a { color: var(--dim); text-decoration: none; }
.crumbs a:hover { color: var(--ink); }
.crumbs [aria-current] { color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 30ch; }

.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem 1rem;
  margin: 0 0 0.85rem;
}
.section-head h2 { margin: 0; }
.section-head a { font-size: 0.9rem; font-weight: 500; color: var(--dim); text-decoration: none; }
.section-head a:hover { color: var(--ink); }
.section-head a .icon { width: 1rem; height: 1rem; }

.panel {
  position: relative;
  margin: 0 0 1.25rem;
  padding: 1.25rem 1.35rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
}
.panel > h2:first-child, .panel > .eyebrow:first-child + h2 { margin-top: 0; }
.panel > h2 { display: flex; align-items: center; gap: 0.6rem; }
.panel > h2 .icon, summary .h2 .icon { width: 1.25rem; height: 1.25rem; color: var(--accent); }
.narrow { max-width: 26rem; margin-left: auto; margin-right: auto; }

.plain { list-style: none; margin: 0; padding: 0; }
.plain > li { padding: 0.8rem 0; border-bottom: 1px solid var(--line); }
.plain > li:first-child { padding-top: 0.15rem; }
.plain > li:last-child { border-bottom: 0; padding-bottom: 0.15rem; }
/* A list drawn as a panel keeps the panel's padding and the gap below it. */
.panel.plain { margin: 0 0 1.25rem; padding: 1rem 1.35rem; }
.plain > li > div { margin-top: 0.15rem; }

.empty { display: flex; align-items: center; gap: 0.9rem; color: var(--dim); }
.empty > .icon { width: 1.75rem; height: 1.75rem; color: var(--faint); }

/* ---- Buttons ------------------------------------------------------------------------------ */
button, .button {
  justify-content: center;
  min-height: 2.75rem;
  padding: 0.6rem 1.15rem;
  font: 600 0.95rem/1.1 var(--sans);
  color: var(--on-bright);
  background: var(--green);
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  box-shadow: var(--glow);
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.15s, box-shadow var(--afterglow), border-color 0.15s, color 0.15s, transform 0.08s;
}
button .icon, .button .icon { width: 1.1rem; height: 1.1rem; stroke-width: 2; }
button:hover, .button:hover {
  background: var(--green-hover);
  box-shadow: 0 0 0 1px rgb(109 255 156 / 0.5), 0 10px 34px -10px rgb(109 255 156 / 0.85);
  transition-duration: 0.15s, var(--glow-in), 0.15s, 0.15s, 0.08s;
}
button:active, .button:active { transform: translateY(1px); }
.button.secondary {
  color: var(--ink);
  background: var(--surface-2);
  border-color: var(--line-2);
  box-shadow: none;
}
.button.secondary:hover { background: var(--surface-3); border-color: var(--edge); box-shadow: none; }
button.quiet, .button.ghost {
  color: var(--ink-2);
  background: transparent;
  border-color: var(--line-2);
  box-shadow: none;
  font-weight: 500;
}
button.quiet:hover, .button.ghost:hover { color: var(--ink); background: var(--surface-2); border-color: var(--edge); box-shadow: none; }
button.danger {
  color: var(--red);
  background: transparent;
  border-color: rgb(255 107 107 / 0.5);
  box-shadow: none;
}
button.danger:hover { background: rgb(255 107 107 / 0.12); border-color: var(--red); box-shadow: none; }
button[disabled], button[disabled]:hover { opacity: 0.45; cursor: not-allowed; box-shadow: none; background: var(--green); transform: none; }

.actions { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; }
.actions form { margin: 0; }
form > button { margin-top: 1rem; }
.actions form > button, .signout > button { margin-top: 0; }

/* ---- Forms -------------------------------------------------------------------------------- */
label {
  display: block;
  margin: 0 0 0.4rem;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--ink-2);
}
.optional { margin-left: 0.3em; font-weight: 400; color: var(--faint); }
input[type="text"],
input[type="password"],
input[type="search"],
input[type="url"],
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input:not([type]),
textarea,
select {
  width: 100%;
  min-height: 2.75rem;
  padding: 0.6rem 0.8rem;
  font: 400 1rem/1.45 var(--sans);
  color: var(--ink);
  caret-color: var(--green);
  background: var(--field);
  border: 1px solid var(--edge);
  border-radius: var(--r-sm);
  transition: border-color var(--afterglow), box-shadow var(--afterglow);
}
input:hover, textarea:hover, select:hover { border-color: var(--dim); }
/* The box being typed in glows: the phosphor, where your attention is. The one you have just
   left keeps its glow a moment. */
input:focus, textarea:focus, select:focus {
  outline: none;
  border-color: var(--green);
  box-shadow: 0 0 0 3px rgb(109 255 156 / 0.16), 0 0 22px -6px rgb(109 255 156 / 0.55);
  transition-duration: var(--glow-in);
}
::placeholder { color: var(--faint); opacity: 1; }
textarea { resize: vertical; min-height: 5rem; }
textarea.script { font: 0.92rem/1.7 var(--mono); }
/* Wide enough for its longest option, so a dropdown never lies about what it holds, but never
   wider than what it sits in. The chevron is drawn as data so the policy lets it through. */
select {
  min-width: min(max-content, 100%);
  padding-right: 2.5rem;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23919e98' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.8rem center;
  background-size: 1rem;
}
select option { color: var(--ink); background: var(--surface); }
input[type="checkbox"], input[type="radio"] {
  width: 1.1rem;
  height: 1.1rem;
  margin: 0 0.45rem 0 0;
  vertical-align: -0.2em;
  accent-color: var(--green);
}

/* Boxes flow into as many columns as fit, and a wide one takes the whole row. */
.form {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 13rem), 1fr));
  gap: 1.1rem 1.25rem;
  align-items: start;
}
.form .wide, .form .field.wide { grid-column: 1 / -1; }
.form .field { min-width: 0; }
.form .actions.end, .filters .actions { align-self: end; }
.form button { margin-top: 0; }
.form fieldset, #google fieldset {
  margin: 0;
  padding: 0.8rem 1rem;
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
}
.form legend, #google legend { padding: 0 0.4rem; font-size: 0.875rem; font-weight: 500; color: var(--ink-2); }
.form .muted { display: block; font-size: 0.85rem; margin-top: 0.35rem; }
.form > p { margin: 0; }
.form .more .inner { margin-top: 0.75rem; }
/* A button that sits at the end of a line of words, such as "Look it up now" on an idea. */
form.inline { display: inline; margin: 0 0 0 0.35rem; }
button.small { min-height: 0; padding: 0.3rem 0.7rem; font-size: 0.85rem; }
label.check, label.inline {
  display: inline-flex;
  align-items: center;
  margin: 0.55rem 1.1rem 0 0;
  font-size: 0.95rem;
  font-weight: 400;
  color: var(--ink);
  cursor: pointer;
}
label.inline { margin: 0 0 0 0.5rem; }
.hint { margin: 0.4rem 0 0; font-size: 0.85rem; color: var(--dim); }
.hint > .icon { margin-right: 0.35rem; color: var(--amber); }

/* Sized by what they hold, and wrapped rather than squeezed: a dropdown squeezed below its
   longest option shows half a word ("any but dropp"). */
.filters { display: flex; flex-wrap: wrap; gap: 0.9rem 1rem; align-items: flex-end; }
.filters .field { flex: 1 0 auto; min-width: 0; }
.filters .field.wide { flex: 3 1 15rem; }
.filters .actions { flex: 0 0 auto; gap: 0.9rem; }
.filters button { margin-top: 0; }
.clear { font-size: 0.9rem; font-weight: 500; color: var(--dim); text-decoration: none; }
.clear:hover { color: var(--ink); }
.count { margin: 0 0 1rem 0.15rem; font-size: 0.9rem; color: var(--dim); }

/* ---- What a form said --------------------------------------------------------------------- */
.said, .error {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  margin: 0 0 1.5rem;
  padding: 0.85rem 1.05rem;
  font-size: 0.95rem;
  border-radius: var(--r);
}
.said { color: var(--ink); background: rgb(109 255 156 / 0.07); border: 1px solid rgb(109 255 156 / 0.28); }
/* A form that worked answers the way an old machine did after a command: OK. */
.said::before {
  content: "OK";
  flex: none;
  padding: 0.22rem 0.36rem 0.18rem;
  font: 500 0.68rem/1 var(--mono);
  letter-spacing: 0.06em;
  color: var(--on-bright);
  background: var(--green);
  border-radius: 4px;
  box-shadow: 0 0 10px rgb(109 255 156 / 0.45);
}
.error { color: #ffd6d6; background: rgb(255 107 107 / 0.08); border: 1px solid rgb(255 107 107 / 0.45); }
.error::before { content: ""; flex: none; width: 0.55rem; height: 0.55rem; background: var(--red); border-radius: 50%; box-shadow: 0 0 8px var(--red); transform: translateY(-0.05rem); }
.setting .error { margin: 0.4rem 0 0; padding: 0.45rem 0.65rem; font-size: 0.85rem; }

/* ---- Small labels ------------------------------------------------------------------------- */
.tag {
  display: inline-flex;
  align-items: center;
  gap: 0.3em;
  padding: 0.18rem 0.6rem;
  font-size: 0.78rem;
  font-weight: 500;
  line-height: 1.35;
  color: var(--ink-2);
  background: rgb(255 255 255 / 0.05);
  border: 1px solid transparent;
  border-radius: 999px;
  white-space: nowrap;
}
.tag.warn { color: var(--amber); background: rgb(255 184 80 / 0.1); }
/* How far off a date is: "tomorrow", "in 2 days". */
.rel { padding: 0.05rem 0.5rem; font-size: 0.75rem; font-weight: 500; color: var(--ink-2); background: var(--surface-3); border-radius: 999px; white-space: nowrap; }
.is-today .rel { color: var(--on-bright); background: var(--amber); }
.status-planned { color: var(--cyan); background: rgb(108 212 255 / 0.12); }
.status-open { color: var(--lemon); background: rgb(247 220 120 / 0.1); }
.status-done { color: var(--green); background: rgb(109 255 156 / 0.1); }
.status-dropped, .status-cancelled { color: var(--dim); text-decoration: line-through; }
.tags { display: flex; flex-wrap: wrap; gap: 0.35rem; margin: 0.25rem 0 0; }
.facts + .tags { margin-top: 1.1rem; }

.kind { font-size: 0.82rem; font-weight: 600; color: var(--kind); }
.kind .icon { width: 1rem; height: 1rem; }

.meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1rem;
  margin: 0;
  font-size: 0.875rem;
  color: var(--dim);
  font-variant-numeric: tabular-nums;
}
.meta .icon { width: 1rem; height: 1rem; color: var(--faint); }
/* The cost is a figure, not a category: in the machine's voice, and in no colour of its own, so
   the one colour on a card is its kind's. */
.meta .cost { font: 500 0.85rem/1 var(--mono); letter-spacing: 0.04em; color: var(--ink-2); }

.facts {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 0.7rem 1.5rem;
  margin: 1.4rem 0 0;
}
.facts dt { font-size: 0.875rem; color: var(--dim); }
.facts dt .icon { width: 1rem; height: 1rem; color: var(--faint); }
.facts dd { margin: 0; overflow-wrap: anywhere; }

.hours, .data { border-collapse: collapse; font-size: 0.9rem; font-variant-numeric: tabular-nums; }
.hours { margin-top: 0.25rem; }
.hours th { text-align: left; font-weight: 400; color: var(--dim); }
.hours td { font-family: var(--mono); font-size: 0.86rem; }
.hours th, .hours td { padding: 0.32rem 1.5rem 0.32rem 0; border-bottom: 1px solid var(--line); }
.data { width: 100%; margin: 0 0 0.25rem; }
.data caption { padding: 0 0 0.6rem; text-align: left; font: 500 0.72rem/1.3 var(--mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--dim); }
.data th {
  padding: 0.5rem 1rem 0.5rem 0;
  text-align: left;
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--dim);
  border-bottom: 1px solid var(--line-2);
}
.data td { padding: 0.5rem 1rem 0.5rem 0; border-bottom: 1px solid var(--line); }
.data tr:last-child td { border-bottom: 0; }
.data .num { text-align: right; font-family: var(--mono); font-size: 0.86rem; }
.data .share { white-space: nowrap; }
.share-cell { display: flex; align-items: center; gap: 0.6rem; font-family: var(--mono); font-size: 0.86rem; }
.share-cell .meter { width: 4.5rem; flex: none; }
/* A table with more columns than a phone has room for scrolls inside itself, not the page. */
.scroll { overflow-x: auto; }
.sources { font-size: 0.85rem; overflow-wrap: anywhere; }

/* A meter filled to a share: the track is quiet, the part used is lit. */
.meter { display: block; width: 100%; height: 6px; overflow: visible; }
.meter-track { fill: var(--line-2); }
.meter-fill { fill: var(--green); }

/* Folded-away detail: native <details>, no script. The chevron turns as it opens. */
summary { cursor: pointer; list-style: none; }
summary::-webkit-details-marker { display: none; }
summary::before {
  content: "";
  flex: none;
  width: 0.45em;
  height: 0.45em;
  margin: 0 0.3em 0 0.15em;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
  transition: transform 0.15s;
}
details[open] > summary::before { transform: rotate(45deg); }
.more > summary { padding: 0.3rem 0; font-size: 0.92rem; font-weight: 600; color: var(--ink-2); }
.more > summary:hover { color: var(--ink); }
.more[open] > summary { margin-bottom: 1rem; }
/* A heading that is also the thing you click, so the page reads the same folded or open. */
.h2 { display: inline-flex; align-items: center; gap: 0.6rem; font-size: 1.2rem; font-weight: 650; letter-spacing: -0.015em; color: var(--ink); }
.panel > summary { display: flex; font-size: 1rem; font-weight: 600; color: var(--ink); }
.panel > summary > .icon { width: 1.2rem; height: 1.2rem; color: var(--accent); }
details.panel[open] > summary { margin-bottom: 1.1rem; }
.actions.row { gap: 1.5rem; margin-top: 0.5rem; }
.danger-zone > summary { color: var(--red); }

/* ---- Cards -------------------------------------------------------------------------------- */
.cards {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 21rem), 1fr));
}
.cards > .panel { margin: 0; }
/* Where a link lands lights up, then fades like phosphor: "4 more on the radar" to what is
   coming, "Change a key" on Status to the keys. */
.panel:target, :target > .panel, .fold:has(> :target) { animation: landed 1.8s cubic-bezier(0.2, 0.7, 0.3, 1); }
.card { display: flex; flex-direction: column; gap: 0.65rem; transition: border-color var(--afterglow), background-color 0.2s, transform 0.2s, box-shadow var(--afterglow); }
.card-kind { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem; margin: 0; }
.card h2 { margin: 0; font-size: 1.12rem; font-weight: 650; line-height: 1.3; color: var(--ink); }
.card h2 a { color: inherit; text-decoration: none; }
/* The whole card is the way in; the few links inside it stay on top. */
.card h2 a::after { content: ""; position: absolute; inset: 0; border-radius: var(--r-lg); }
.card .links a, .card .tags { position: relative; z-index: 1; }
.card:has(h2 a):hover {
  background: var(--surface-2);
  border-color: color-mix(in srgb, var(--accent) 40%, var(--line));
  box-shadow: var(--shadow), 0 0 40px -18px color-mix(in srgb, var(--accent) 60%, transparent);
  transform: translateY(-2px);
}
.card-id { margin-top: auto; align-self: flex-end; font: 0.75rem/1 var(--mono); color: var(--faint); }
.summary { margin: 0; color: var(--ink-2); }
.links { display: flex; flex-wrap: wrap; gap: 0.4rem 1.2rem; margin: 0.1rem 0 0; font-size: 0.9rem; font-weight: 500; }
.links a { text-decoration: none; }
.links .icon { width: 1rem; height: 1rem; }
.today-hours { margin: 0; font-size: 0.875rem; font-weight: 500; color: var(--amber); }
.today-hours .icon { width: 1rem; height: 1rem; }

/* Two ways of looking at the same list, as a segmented control. */
.tabs {
  display: flex;
  width: fit-content;
  max-width: 100%;
  gap: 0.25rem;
  margin: 0 0 1.25rem;
  padding: 0.25rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 13px;
}
.tabs a { padding: 0.5rem 0.95rem; font-size: 0.92rem; font-weight: 500; text-decoration: none; color: var(--dim); border-radius: 10px; }
.tabs a:hover { color: var(--ink); }
.tabs a[aria-current="page"] { color: var(--ink); background: var(--surface-3); box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.05); }
.tabs a[aria-current="page"] .icon { color: var(--accent); }
.tabs .icon { width: 1.05rem; height: 1.05rem; }

/* The quick note on the ideas page, which Chat turns into an idea. */
.capture > p { max-width: 70ch; margin: 0 0 1rem; color: var(--dim); }
.capture > summary > .icon { color: var(--green); }
@media (min-width: 44rem) {
  .capture .form { grid-template-columns: minmax(0, 1fr) 15rem; align-items: end; }
  .capture .form .field.wide { grid-column: 1; grid-row: 1 / span 2; }
  .capture .form .field.wide textarea { min-height: 8.3rem; }
  .capture .form .actions.end button { width: 100%; }
  .capture .form .hint { grid-column: 1 / -1; }
}

/* ---- Home --------------------------------------------------------------------------------- */
/* The greeting, lit from below like a screen in a dark room. */
.welcome {
  position: relative;
  display: grid;
  gap: 1.75rem;
  align-items: center;
  margin: 0 0 2.25rem;
  padding: clamp(1.1rem, 4.5vw, 2.75rem);
  overflow: hidden;
  background:
    radial-gradient(70% 90% at 0% 100%, rgb(109 255 156 / 0.13), transparent 62%),
    radial-gradient(45% 70% at 100% 0%, rgb(108 212 255 / 0.07), transparent 70%),
    var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow);
}
/* A whisper of scanlines inside the glow, and only there. */
.welcome::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(to bottom, rgb(255 255 255 / 0.028) 0 1px, transparent 1px 4px);
  -webkit-mask-image: radial-gradient(60% 90% at 0% 100%, #000, transparent 75%);
  mask-image: radial-gradient(60% 90% at 0% 100%, #000, transparent 75%);
}
.welcome-words { position: relative; min-width: 0; }
/* Who is asking, signed as her lines in the chat are: her screen, her name, and the day. */
.speaker { display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem 0.7rem; margin: 0 0 1rem; }
.speaker strong { font-size: 1.05rem; font-weight: 650; letter-spacing: -0.01em; }
/* Her question is the box's label, printed in its frame above where you write: the page's
   heading, and the way in, since a tap on it puts you in the box. */
.ask-question { margin: 0; padding: 0.75rem 0.8rem 0; font-size: clamp(1.3rem, 2.4vw, 1.6rem); line-height: 1.2; letter-spacing: -0.022em; }
.ask-question label { display: block; margin: 0; font: inherit; color: var(--ink); cursor: text; }
.ask .ask-question + textarea { min-height: 3rem; padding-top: 0.35rem; }
/* The page's first question and the box to answer it in. The box is the chat's own; here, where
   it is the first thing to do, its edge keeps a faint phosphor even at rest, and lights up fully
   while you write. */
.welcome .ask {
  background: rgb(9 12 11 / 0.72);
  border-color: color-mix(in srgb, var(--green) 30%, var(--edge));
  box-shadow: var(--shadow), 0 0 38px -20px rgb(109 255 156 / 0.6);
}
.welcome .ask:focus-within { border-color: var(--green); box-shadow: var(--shadow), 0 0 0 3px rgb(109 255 156 / 0.14), 0 0 30px -8px rgb(109 255 156 / 0.5); }
/* How the conversation stands, under the box: her last line, drawn as the chat draws it but cut
   to three lines, or what she is waiting on; the whole of it is a tap away. */
.thread.brief { margin: 1.4rem 0 0; }
.brief > li { max-width: none; }
.brief .said-text { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; }
.brief .pending .said-text { display: block; }
.brief-more { margin: 0.45rem 0 0 2.9rem; font-size: 0.9rem; font-weight: 500; }
.brief-more a { display: inline-flex; align-items: center; gap: 0.35em; text-decoration: none; }
.brief-more .icon { width: 1rem; height: 1rem; }
/* What is next, on a green screen, beside the radar that shows it. On a phone the words run
   round the scope. */
.next-up .crt-tube { display: flow-root; }
.next-up .radar {
  float: right;
  width: 6.5rem;
  margin: 0.2rem 0 0.4rem 0.8rem;
  shape-outside: circle(50%) border-box;
  shape-margin: 0.55rem;
}
.next-text { min-width: 0; }
.next-up .next-label { margin: 0 0 0.55rem; font-size: 1.2rem; letter-spacing: 0.08em; }
.next-up .next-title { font-size: 1.95rem; line-height: 1; overflow-wrap: anywhere; }
.next-up .next-when { margin-top: 0.4rem; font-size: 1.4rem; }
.next-up .rel, .on-radar .rel {
  padding: 0;
  font: inherit;
  color: var(--phosphor-bright);
  text-transform: uppercase;
  background: none;
  border-radius: 0;
}
.next-up .rel::before, .on-radar .rel::before { content: "["; }
.next-up .rel::after, .on-radar .rel::after { content: "]"; }
.next-up .next-where { font-size: 1.4rem; }
.next-up .next-more { margin-top: 0.6rem; font-size: 1.4rem; }
.next-up .radar-label { display: none; }
@media (min-width: 40rem) {
  .next-up .crt-tube { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 1.25rem; align-items: center; }
  .next-up .radar { float: none; grid-column: 2; grid-row: 1; width: 9rem; margin: 0; }
  .next-up .radar-label { display: inline; }
  .next-text { grid-column: 1; grid-row: 1; }
}
@media (min-width: 64rem) {
  .welcome { grid-template-columns: minmax(0, 1.35fr) minmax(22rem, 1fr); }
}

.setup {
  --accent: var(--amber);
  background: linear-gradient(135deg, rgb(255 184 80 / 0.08), transparent 55%), var(--surface);
  border-color: rgb(255 184 80 / 0.35);
}
.setup ol { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.6rem; }
.setup li { display: flex; gap: 0.75rem; align-items: baseline; }
.setup li::before { content: ""; flex: none; width: 0.85rem; height: 0.85rem; border: 2px solid var(--amber); border-radius: 50%; transform: translateY(0.12rem); }
.setup a { color: var(--ink); text-decoration-color: rgb(255 184 80 / 0.5); }
.setup a:hover { color: var(--amber); }
.setup > p { margin: 1rem 0 0; font-size: 0.92rem; }

.dashboard { display: grid; gap: 1rem 2rem; }
.dashboard-column { min-width: 0; }
.source { margin: -0.35rem 0 0.9rem; font-size: 0.875rem; }
.source-unavailable { color: var(--amber); }
/* A section head with two ways on: add one, or see them all. */
.section-links { display: flex; flex-wrap: wrap; gap: 0.25rem 1.1rem; }

/* What is left to do, each with a tick that marks it done where it stands. */
.home-todo { --accent: var(--lemon); }
.checklist > li { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 0.6rem; align-items: center; }
.checklist > li.empty { display: flex; }
.checklist .what { font-size: 1.02rem; font-weight: 600; line-height: 1.35; overflow-wrap: anywhere; }
.checklist .when { display: flex; flex-wrap: wrap; gap: 0.15rem 0.8rem; margin-top: 0.15rem; font-size: 0.875rem; color: var(--dim); }
.checklist .when .warn { color: var(--amber); }
/* An empty box to tick, on a target a thumb can find; pointed at, it shows the tick it will make. */
button.tick {
  position: relative;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  min-height: 0;
  margin: -0.35rem 0 -0.35rem -0.6rem;
  padding: 0;
  color: transparent;
  background: none;
  border: 0;
  border-radius: 12px;
  box-shadow: none;
}
button.tick::before {
  content: "";
  position: absolute;
  width: 1.4rem;
  height: 1.4rem;
  border: 2px solid var(--edge);
  border-radius: 7px;
  transition: border-color var(--afterglow), background-color 0.15s, box-shadow var(--afterglow);
}
button.tick .icon { position: relative; width: 0.9rem; height: 0.9rem; stroke-width: 3; }
button.tick:hover { color: var(--accent); background: none; box-shadow: none; }
button.tick:hover::before { border-color: var(--accent); box-shadow: 0 0 14px -4px color-mix(in srgb, var(--accent) 75%, transparent); transition-duration: var(--glow-in); }
button.tick:active { color: var(--on-bright); }
button.tick:active::before { background: var(--accent); border-color: var(--accent); }
.tick-form { margin: 0; }
/* On a task's card the box sits level with the first line of its title. */
.task-head .tick { margin: -0.65rem 0 -0.65rem -0.675rem; }

.idea-cards { display: grid; gap: 0.85rem; grid-template-columns: repeat(auto-fill, minmax(min(100%, 12.5rem), 1fr)); margin-bottom: 0.85rem; }
.idea-card {
  --accent: var(--lilac);
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  margin: 0;
  color: var(--ink);
  text-decoration: none;
  transition: border-color var(--afterglow), background-color 0.2s, transform 0.2s, box-shadow var(--afterglow);
}
.idea-card strong { font-size: 1rem; font-weight: 650; line-height: 1.3; }
.idea-card .muted { font-size: 0.9rem; }
.idea-card:hover, .card:has(h2 a):hover {
  transition-duration: var(--glow-in), 0.15s, 0.2s, var(--glow-in);
}
.idea-card:hover {
  background: var(--surface-2);
  border-color: color-mix(in srgb, var(--accent) 40%, var(--line));
  box-shadow: var(--shadow), 0 0 40px -18px color-mix(in srgb, var(--accent) 60%, transparent);
  transform: translateY(-2px);
}
.restaurants-link {
  --accent: var(--amber);
  display: flex;
  align-items: center;
  gap: 1rem;
  color: var(--ink);
  text-decoration: none;
  background: linear-gradient(120deg, rgb(255 184 80 / 0.12), transparent 70%), var(--surface);
  border-color: rgb(255 184 80 / 0.3);
  transition: border-color var(--afterglow), box-shadow var(--afterglow);
}
.restaurants-link:hover { border-color: rgb(255 184 80 / 0.6); box-shadow: var(--shadow), 0 0 40px -18px rgb(255 184 80 / 0.7); transition-duration: var(--glow-in); }
.restaurants-link .eyebrow { color: var(--amber); }
.restaurants-link strong { display: block; margin-top: 0.2rem; font-size: 1.15rem; font-weight: 650; }
.restaurants-icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 3rem;
  height: 3rem;
  color: var(--amber);
  background: rgb(255 184 80 / 0.1);
  border: 1px solid rgb(255 184 80 / 0.3);
  border-radius: 13px;
}
.restaurants-icon .icon { width: 1.4rem; height: 1.4rem; }
.go { margin-left: auto; color: var(--accent); }

@media (min-width: 52rem) {
  .dashboard { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); align-items: start; }
}

/* ---- Dates -------------------------------------------------------------------------------- */
/* A plan's day as a small calendar leaf: the month in the plans' cyan, the day large. */
.agenda > li { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 1rem; align-items: center; }
.chip {
  display: grid;
  justify-items: center;
  width: 3.4rem;
  padding: 0.4rem 0 0.45rem;
  line-height: 1;
  background: var(--surface-2);
  border: 1px solid var(--line-2);
  border-radius: 13px;
}
.chip-mon { font: 500 0.66rem/1 var(--mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--cyan); }
.chip-day { margin: 0.2rem 0 0.18rem; font-size: 1.45rem; font-weight: 700; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.chip-dow { font-size: 0.68rem; color: var(--dim); }
.chip.is-today { border-color: rgb(255 184 80 / 0.55); box-shadow: 0 0 22px -8px rgb(255 184 80 / 0.7); }
.chip.is-today .chip-mon, .chip.is-today .chip-day { color: var(--amber); }
.agenda-body { min-width: 0; }
.agenda .what { font-size: 1.02rem; font-weight: 600; line-height: 1.35; }
.agenda .what a { color: var(--ink); text-decoration-color: rgb(255 255 255 / 0.22); }
.agenda .what a:hover { color: var(--cyan); text-decoration-color: currentColor; }
.agenda .when { display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem 0.55rem; margin-top: 0.2rem; font-size: 0.875rem; color: var(--ink-2); }
.agenda .where, .agenda .note { margin-top: 0.2rem; font-size: 0.875rem; color: var(--dim); }
.agenda .where { display: flex; align-items: flex-start; gap: 0.35rem; }
.agenda .where .icon { width: 0.95rem; height: 0.95rem; margin-top: 0.2rem; color: var(--faint); }
.agenda > li.empty { display: flex; }
.past .chip-mon, .past .chip-day { color: var(--dim); }
.past .agenda .what, .past .agenda .what a { color: var(--ink-2); }

/* ---- Green screens ------------------------------------------------------------------------ */
/* The page's pictures are old green-screen monitors, as on a desk in 1984 (`crt` in _ui.html):
   a tube of dark glass in a plastic surround with its power light on, and on it words drawn in
   phosphor. The words are VT323, a terminal's face, blurred a third of a pixel and blooming, in
   the three strengths a monitor drew (dim, normal and bright) and in inverse video, with a block
   cursor waiting after the last line. Scanlines, a little light off the front and the tube's
   dark, curved edge lie over it all. Only the screens are hazy; around them the page is sharp.
   One to a page at most, and only where there is something to show: what is next, the way in,
   the page that is not there or not yours, the day's spend, and where the listed ideas are. */
.crt {
  --phosphor: var(--green);
  --phosphor-bright: color-mix(in srgb, var(--phosphor) 45%, #fff);
  --phosphor-dim: color-mix(in srgb, var(--phosphor) 64%, #07120c);
  --phosphor-glass: color-mix(in srgb, var(--phosphor) 9%, #060a08);
  position: relative;
  padding: 0.65rem 0.65rem 1.5rem;
  background: linear-gradient(180deg, #1d2321, #151a18 45%, #101412);
  border: 1px solid #2c3431;
  border-radius: 24px;
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.08),
    inset 0 -2px 3px rgb(0 0 0 / 0.35),
    0 28px 50px -34px rgb(0 0 0 / 0.95),
    0 0 80px -36px color-mix(in srgb, var(--phosphor) 45%, transparent);
}
/* The power light, in the chin. */
.crt::after {
  content: "";
  position: absolute;
  right: 1.25rem;
  bottom: 0.55rem;
  width: 0.4rem;
  height: 0.4rem;
  background: var(--phosphor);
  border-radius: 50%;
  box-shadow: 0 0 6px var(--phosphor);
}
.crt-tube {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding: 1rem 1.2rem 1.1rem;
  color: var(--phosphor);
  font: 400 1.5rem/1.15 var(--terminal);
  background: radial-gradient(125% 115% at 50% 40%, var(--phosphor-glass), #07100b 55%, #030705);
  border-radius: 17px / 19px;
  box-shadow: inset 0 0 0 1.5px #020403, inset 0 0 36px 6px rgb(0 0 0 / 0.72);
  text-shadow:
    0 0 1px color-mix(in srgb, var(--phosphor) 80%, transparent),
    0 0 9px color-mix(in srgb, var(--phosphor) 45%, transparent),
    0 0 24px color-mix(in srgb, var(--phosphor) 20%, transparent);
}
.crt-tube p { margin: 0; }
/* The phosphor is soft: everything on the screen is blurred by a third of a pixel. */
.crt-tube > :not(.radar) { position: relative; filter: blur(0.35px); }
/* Scanlines over it all, and over those the glass: a little light off the front, and the tube's
   dark, curved edge. */
.crt-tube::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background: repeating-linear-gradient(to bottom, rgb(2 5 3 / 0.4) 0 1px, transparent 1px 3px);
}
.crt-tube::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  border-radius: inherit;
  background:
    radial-gradient(85% 50% at 26% 4%, rgb(255 255 255 / 0.075), transparent 62%),
    radial-gradient(135% 125% at 50% 42%, transparent 55%, rgb(0 0 0 / 0.6));
}
/* The three strengths a monitor drew in, and inverse video, which a link turns to when pointed
   at, as a menu's choice did. */
.crt .bright { color: var(--phosphor-bright); }
.crt .dim { color: var(--phosphor-dim); text-shadow: 0 0 6px color-mix(in srgb, var(--phosphor) 25%, transparent); }
.crt .inverse, .crt a:hover {
  color: #04100a;
  background: var(--phosphor);
  text-decoration: none;
  text-shadow: none;
  box-shadow: 0 0 14px color-mix(in srgb, var(--phosphor) 55%, transparent);
}
.crt .inverse { padding: 0 0.3em; }
.crt a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, currentColor 55%, transparent);
  text-decoration-thickness: 2px;
  text-underline-offset: 0.16em;
}
.crt a:focus-visible { outline-color: var(--phosphor); }
.crt .caps { text-transform: uppercase; letter-spacing: 0.08em; }
/* The block cursor, waiting for the next line. */
.crt-cursor {
  display: inline-block;
  width: 0.45em;
  height: 0.62em;
  margin-left: 0.2em;
  background: currentColor;
  box-shadow: 0 0 8px currentColor;
  animation: blink 1.06s steps(1) 10;
}
/* Switched on as the page opens: the picture opens out of a bright line, as a tube warming up
   did. Only on a page seen now and then, so it never stands between anyone and what they need. */
.crt.power-on .crt-tube > * { animation: power-on 0.6s cubic-bezier(0.2, 0.7, 0.2, 1); }

/* The radar: a program the green screen can run (`radar` in _ui.html). Range rings a week, two
   weeks and four weeks out, "now" at the middle; a sweep that leaves an afterglow, as a
   long-persistence phosphor did; each plan a blip that flares as the sweep passes and fades
   until it comes round again, the next one pinging. On Ideas the same scope is a map of places.
   Hidden from screen readers, and never the only place anything is said. */
.radar {
  --sweep: 8s;
  position: relative;
  flex: none;
  aspect-ratio: 1;
  overflow: hidden;
  isolation: isolate;
  background: radial-gradient(closest-side, #10271a, #0a1811 60%, #060e0a);
  border-radius: 50%;
  outline: 1px solid rgb(109 255 156 / 0.2);
  outline-offset: 4px;
  box-shadow: 0 0 48px -12px rgb(109 255 156 / 0.5);
}
.radar svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  filter: blur(0.35px) drop-shadow(0 0 2px rgb(109 255 156 / 0.55));
}
.radar svg * { vector-effect: non-scaling-stroke; }
.radar-rim { fill: none; stroke: rgb(109 255 156 / 0.4); stroke-width: 1; }
.radar-ring { fill: none; stroke: rgb(109 255 156 / 0.2); stroke-width: 1; }
.radar-cross { fill: none; stroke: rgb(109 255 156 / 0.12); stroke-width: 1; }
.radar-ticks { fill: none; stroke: rgb(109 255 156 / 0.42); stroke-width: 1; }
.radar-hub { fill: rgb(146 255 184 / 0.75); }
.radar-label { font: 500 10px var(--mono); fill: rgb(109 255 156 / 0.55); }
/* The sweep: a bright edge, and the afterglow it leaves behind as it turns. */
.radar-sweep {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(
    transparent 0deg 230deg,
    rgb(109 255 156 / 0.04) 255deg,
    rgb(109 255 156 / 0.12) 315deg,
    rgb(109 255 156 / 0.26) 350deg,
    rgb(146 255 184 / 0.45) 360deg
  );
  animation: sweep var(--sweep) linear infinite;
}
.radar-sweep::after {
  content: "";
  position: absolute;
  left: calc(50% - 0.5px);
  top: 1%;
  width: 1px;
  height: 49%;
  background: linear-gradient(to top, rgb(146 255 184 / 0.15), rgb(210 255 225 / 0.9));
  box-shadow: 0 0 6px 1px rgb(109 255 156 / 0.55);
}
/* A plan, or a place: a hot centre in a soft halo, dimming between passes but never out. */
.blip { opacity: 0.9; animation: blip var(--sweep) cubic-bezier(0.15, 0.7, 0.35, 1) infinite var(--at, 0s); }
.blip-halo { fill: rgb(109 255 156 / 0.24); }
.blip-core { fill: #a9ffc7; }
.blip.next { --rest: 0.62; opacity: 1; }
.blip.next .blip-halo { fill: rgb(109 255 156 / 0.4); }
.blip.next .blip-core { fill: #e4fff0; }
.blip-ping {
  fill: none;
  stroke: rgb(146 255 184 / 0.9);
  stroke-width: 1;
  opacity: 0.4;
  transform: scale(2.2);
  transform-box: fill-box;
  transform-origin: center;
  animation: ping var(--sweep) cubic-bezier(0.15, 0.7, 0.35, 1) infinite var(--at, 0s);
}
/* Each blip flares as the sweep reaches its bearing, one of twelve (`views.radar_blips`);
   bearing 0, at twelve o'clock, needs no delay. */
.b1 { --at: calc(var(--sweep) * -11 / 12); }
.b2 { --at: calc(var(--sweep) * -10 / 12); }
.b3 { --at: calc(var(--sweep) * -9 / 12); }
.b4 { --at: calc(var(--sweep) * -8 / 12); }
.b5 { --at: calc(var(--sweep) * -7 / 12); }
.b6 { --at: calc(var(--sweep) * -6 / 12); }
.b7 { --at: calc(var(--sweep) * -5 / 12); }
.b8 { --at: calc(var(--sweep) * -4 / 12); }
.b9 { --at: calc(var(--sweep) * -3 / 12); }
.b10 { --at: calc(var(--sweep) * -2 / 12); }
.b11 { --at: calc(var(--sweep) * -1 / 12); }
/* Words on the scope itself, drawn in the phosphor: the 404, or the 403. */
.radar-say {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font: 500 clamp(3.25rem, 15vw, 4.75rem)/1 var(--mono);
  letter-spacing: -0.04em;
  color: var(--green);
  text-shadow: 0 0 0.3em rgb(109 255 156 / 0.6), 0 0 0.9em rgb(109 255 156 / 0.28);
  filter: blur(0.4px);
  animation: flicker 6s linear infinite;
}
/* On a green screen the radar is drawn on the same glass: no ring of its own, no glass. */
.crt .radar { background: none; outline: 0; box-shadow: none; }
.crt .radar::after { display: none; }
.crt .radar-say { font: 400 clamp(3.5rem, 16vw, 4.75rem)/1 var(--terminal); letter-spacing: 0; }
/* Glass over it all: scanlines, the tube's dark edge, and a little light off the front. */
.radar::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  pointer-events: none;
  background:
    radial-gradient(80% 60% at 30% 16%, rgb(255 255 255 / 0.075), transparent 50%),
    repeating-linear-gradient(to bottom, rgb(3 7 5 / 0.38) 0 1px, transparent 1px 3px),
    radial-gradient(closest-side, transparent 66%, rgb(0 0 0 / 0.55));
  box-shadow: inset 0 0 0 1px rgb(109 255 156 / 0.12);
}

/* ---- Chat --------------------------------------------------------------------------------- */
/* Hers on the left beside her screen, the family's on the right with their initial: side and
   mark tell them apart, so colour never has to. */
.in-chat main { max-width: 52rem; }
.thread { list-style: none; margin: 0 0 1.5rem; padding: 0; display: flex; flex-direction: column; gap: 1.1rem; }
.thread > li { display: flex; gap: 0.7rem; align-items: flex-end; max-width: min(42rem, 100%); }
.said-them { flex-direction: row-reverse; margin-left: auto; }
.avatar {
  display: grid;
  place-items: center;
  flex: none;
  width: 2.2rem;
  height: 2.2rem;
  font-size: 0.95rem;
  font-weight: 700;
  border-radius: 50%;
}
/* Her screen. Vera is never drawn: no face, no figure, no picture of her; she stays behind the
   glass. Where the page shows her there is a small screen full of words nobody can read, as if
   busy, somewhere between a 1980s terminal and the Matrix's falling code: columns of glyphs in
   the terminal's face, the newest of each run bright and the rest dim, scanned and blurred past
   reading. They are drawn here and mean nothing. They fall while she thinks, and on Home for a
   moment as the page opens. Beside her lines and her name, on her page, beside "Who answers" on
   Status, and where the settings speak of her. The mark with its smile is the page's own,
   FamilyDB's, and never hers. */
.presence, .title-icon.presence, .section-icon.presence {
  position: relative;
  overflow: hidden;
  background: radial-gradient(circle at 50% 45%, rgb(109 255 156 / 0.16), #06110b 72%);
  border: 1px solid rgb(109 255 156 / 0.32);
  box-shadow: 0 0 18px -6px rgb(109 255 156 / 0.6);
}
.avatar.presence { border-radius: 11px; }
.glyph.presence { display: inline-block; flex: none; width: 1.1rem; height: 1.1rem; border-radius: 4px; box-shadow: 0 0 10px -3px rgb(109 255 156 / 0.65); }
.presence-glass {
  position: absolute;
  inset: 0;
  font-size: 6px;
  /* Scanlines across the words themselves, as a tube drew them. */
  -webkit-mask-image: repeating-linear-gradient(to bottom, #000 0 2px, rgb(0 0 0 / 0.4) 2px 3px);
  mask-image: repeating-linear-gradient(to bottom, #000 0 2px, rgb(0 0 0 / 0.4) 2px 3px);
}
.title-icon .presence-glass { font-size: 6.5px; }
.section-icon .presence-glass { font-size: 7px; }
.glyph .presence-glass { font-size: 4px; }
/* Two layers of the same grid: the trails, dim, and the head of each run, bright. The pattern is
   sixteen rows, three times over, so the fall can go round without a seam. */
.presence-glass::before, .presence-glass::after {
  position: absolute;
  top: calc(var(--from, 0) * -0.85em);
  left: calc(var(--across, 0) * -1ch);
  font: 400 1em/0.85 var(--terminal);
  white-space: pre;
  filter: blur(0.3px);
}
.presence-glass::before {
  content: " >   : HJ     6\A        D   6  1\A        : 40   9 50\A X  J1    3   *>>D\A 7 S E    >   Z\A |A5 N7   K8FNQ   0\A  ER Q2N 0V0 H  F J\A  >6 2R3 A   E\A  KT  KE      2\A    F  2  D6  4=78\A          HA   <94\A F      F J E5 8V4\A VR   1   *  K |6NQ\A WE V    6   M    |\A 4+<   N 8 V5V    V\A  QD  ER F D FQ   |\A  >   : HJ     6\A        D   6  1\A        : 40   9 50\A X  J1    3   *>>D\A 7 S E    >   Z\A |A5 N7   K8FNQ   0\A  ER Q2N 0V0 H  F J\A  >6 2R3 A   E\A  KT  KE      2\A    F  2  D6  4=78\A          HA   <94\A F      F J E5 8V4\A VR   1   *  K |6NQ\A WE V    6   M    |\A 4+<   N 8 V5V    V\A  QD  ER F D FQ   |\A  >   : HJ     6\A        D   6  1\A        : 40   9 50\A X  J1    3   *>>D\A 7 S E    >   Z\A |A5 N7   K8FNQ   0\A  ER Q2N 0V0 H  F J\A  >6 2R3 A   E\A  KT  KE      2\A    F  2  D6  4=78\A          HA   <94\A F      F J E5 8V4\A VR   1   *  K |6NQ\A WE V    6   M    |\A 4+<   N 8 V5V    V\A  QD  ER F D FQ   |";
  color: rgb(109 255 156 / 0.62);
  text-shadow: 0 0 2px rgb(109 255 156 / 0.55);
}
.presence-glass::after {
  content: "  V   6   A J*   W\A  D   3  6\A            1\A        X  S      S\A    Q          H00\A \A T          + =\A          5Q    1 *\A     =   1   R\A  KZ  |\A    R  0      K\A           9\A        3   0\A      F   S    T++\A    >\A M          E\A   V   6   A J*   W\A  D   3  6\A            1\A        X  S      S\A    Q          H00\A \A T          + =\A          5Q    1 *\A     =   1   R\A  KZ  |\A    R  0      K\A           9\A        3   0\A      F   S    T++\A    >\A M          E\A   V   6   A J*   W\A  D   3  6\A            1\A        X  S      S\A    Q          H00\A \A T          + =\A          5Q    1 *\A     =   1   R\A  KZ  |\A    R  0      K\A           9\A        3   0\A      F   S    T++\A    >\A M          E";
  color: #dcffe8;
  text-shadow: 0 0 2px #a9ffc7, 0 0 5px rgb(109 255 156 / 0.85);
}
/* Another part of the same screen for each of her lines, so a thread of them is not a row of
   copies. */
.presence.v1 { --from: 4; --across: 3; }
.presence.v2 { --from: 8; --across: 1; }
.presence.v3 { --from: 12; --across: 5; }
.said-them .avatar { color: var(--on-bright); background: var(--amber); }
.bubble { min-width: 0; padding: 0.75rem 1rem 0.85rem; border-radius: 20px; }
.said-bot .bubble { background: var(--surface); border: 1px solid var(--line); border-bottom-left-radius: 6px; }
.said-them .bubble { background: var(--surface-3); border: 1px solid var(--line-2); border-bottom-right-radius: 6px; }
.said-by { display: flex; flex-wrap: wrap; gap: 0.15rem 0.6rem; align-items: baseline; margin-bottom: 0.3rem; font-size: 0.78rem; color: var(--dim); }
.said-by strong { font-weight: 600; color: var(--ink-2); }
.said-them .said-by { flex-direction: row-reverse; }
/* Replies keep the line breaks the model wrote; escaping still happens, this is only layout. */
.said-text { white-space: pre-wrap; overflow-wrap: anywhere; line-height: 1.55; }
.did { margin-top: 0.6rem; font: 0.74rem/1.4 var(--mono); color: var(--faint); }
/* While the newest message waits, the page says so in her place, as the thread's last line: her
   screen and name, the same bubble drawn in a dashed line, because the words are the page's, not
   hers. While she is thinking the glyphs on her screen fall; nothing is shown typing. On Home,
   which never looks again, they fall only for a moment as the page opens (see "Her screen"). */
.pending .bubble { background: transparent; border: 1px dashed var(--line-2); }
.pending .said-text { color: var(--ink-2); }
.pending.is-lost .bubble { border-color: rgb(255 184 80 / 0.45); }
.thread:not(.brief) .pending.is-thinking .presence-glass::before,
.thread:not(.brief) .pending.is-thinking .presence-glass::after { animation: fall 2.4s steps(16) infinite; }
.speaker .presence-glass::before, .speaker .presence-glass::after { animation: fall 2.4s steps(16) 1; }

/* The box: the message on top, who is sending and Send along the bottom, all in one frame that
   lights up while you write. */
.ask {
  margin: 0;
  padding: 0.35rem 0.35rem 0.5rem;
  background: var(--surface);
  border: 1px solid var(--edge);
  border-radius: 20px;
  box-shadow: var(--shadow);
  transition: border-color var(--afterglow), box-shadow var(--afterglow);
}
.ask:focus-within { border-color: var(--green); box-shadow: var(--shadow), 0 0 0 3px rgb(109 255 156 / 0.14), 0 0 30px -8px rgb(109 255 156 / 0.5); transition-duration: var(--glow-in); }
.ask textarea {
  min-height: 5rem;
  padding: 0.7rem 0.8rem;
  background: transparent;
  border: 0;
  box-shadow: none;
  resize: vertical;
}
.ask textarea:focus { box-shadow: none; }
/* Closed while an answer is on its way: the page is about to look again, and would take anything
   typed with it. The frame goes quiet and the box says when it opens. */
.ask:has(textarea:disabled) { border-color: var(--line-2); }
.ask textarea:disabled { cursor: not-allowed; }
.ask-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem 1rem; padding: 0.35rem 0.4rem 0 0.8rem; }
.ask .who { display: flex; align-items: center; gap: 0.5rem; min-width: 0; }
.ask .who label, .ask .who .from { margin: 0; font-size: 0.875rem; color: var(--dim); }
.ask .who .from strong { color: var(--ink); font-weight: 600; }
.ask .who select { min-height: 2.4rem; padding-top: 0.35rem; padding-bottom: 0.35rem; font-size: 0.95rem; background-color: var(--surface-2); border-color: var(--line-2); }
.ask .locate label { display: inline-flex; align-items: center; gap: 0.35rem; margin: 0; font-size: 0.9rem; font-weight: 400; color: var(--ink-2); cursor: pointer; }
.ask .locate .icon { width: 1.05rem; height: 1.05rem; color: var(--amber); }
.ask .send { margin: 0 0 0 auto; }
/* On a phone the bar keeps to two rows: who is sending and Send, which shows only its arrow, and
   under them "Send where I am". */
@media (max-width: 30rem) {
  .ask-bar { gap: 0.5rem 0.75rem; padding-left: 0.6rem; }
  .ask .locate { order: 3; flex-basis: 100%; }
  .ask .send { width: 2.75rem; padding: 0; }
  .ask .send .label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .ask .send .icon { width: 1.25rem; height: 1.25rem; }
}
#where { margin: 0.4rem 0 0 0.8rem; font-size: 0.85rem; }
#where:empty { display: none; }
/* Ways to start, under the box: quiet outlined pills that light up when pointed at, and step
   aside once something is written (ask.js). */
.starters { display: flex; flex-wrap: wrap; gap: 0.5rem; list-style: none; margin: 0.85rem 0 0; padding: 0; }
.starters a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  padding: 0.4rem 0.95rem;
  font-size: 0.9rem;
  font-weight: 500;
  line-height: 1.25;
  color: var(--ink-2);
  text-decoration: none;
  background: rgb(255 255 255 / 0.025);
  border: 1px solid var(--line-2);
  border-radius: 999px;
  transition: color 0.15s, background-color 0.15s, border-color var(--afterglow);
}
.starters a:hover { color: var(--ink); background: rgb(109 255 156 / 0.06); border-color: rgb(109 255 156 / 0.45); transition-duration: 0.15s, 0.15s, var(--glow-in); }
@media (pointer: fine) { .starters a { min-height: 2.3rem; } }

/* ---- Ideas -------------------------------------------------------------------------------- */
/* Where the listed places are, on a green screen laid out as Next up is: the radar beside the
   words that say what it shows, the words running round it on a phone. It is a map, so it is
   drawn larger. */
.on-radar { margin: 0 0 1.25rem; }
.on-radar .crt-tube { display: flow-root; }
.on-radar .radar {
  float: right;
  width: 7.5rem;
  margin: 0.2rem 0 0.4rem 0.8rem;
  shape-outside: circle(50%) border-box;
  shape-margin: 0.55rem;
}
.on-radar .radar-label { display: none; }
.on-radar-label { margin: 0 0 0.55rem; font-size: 1.2rem; letter-spacing: 0.08em; }
.on-radar-count { font-size: 1.95rem; line-height: 1; }
.on-radar-line { margin-top: 0.4rem; font-size: 1.4rem; overflow-wrap: anywhere; }
.on-radar-more { margin-top: 0.6rem; font-size: 1.2rem; }
@media (min-width: 40rem) {
  .on-radar .crt-tube { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 1.5rem; align-items: center; }
  .on-radar .radar { float: none; grid-column: 2; grid-row: 1; width: 13rem; margin: 0; }
  .on-radar .radar-label { display: inline; }
  .on-radar-text { grid-column: 1; grid-row: 1; }
}

/* ---- An idea ------------------------------------------------------------------------------ */
.split { display: grid; gap: 1.25rem; grid-template-areas: "main" "side" "place"; }
.split > * { min-width: 0; margin: 0; }
.idea-main { grid-area: main; }
.idea-side { grid-area: side; }
.idea-place { grid-area: place; }
.idea-side > .panel:last-child { margin-bottom: 0; }
.idea-main h1 { margin: 0.75rem 0 0.8rem; overflow-wrap: anywhere; }
.description { max-width: 62ch; margin: 1rem 0 0; font-size: 1.08rem; line-height: 1.6; color: var(--ink-2); }
.original { margin-top: 1rem; }
.original .said-text { color: var(--dim); padding-left: 0.9rem; border-left: 2px solid var(--line-2); }
.idea-main .actions { margin-top: 1.5rem; padding-top: 1.25rem; border-top: 1px solid var(--line); }
.outcomes .score { color: var(--amber); background: rgb(255 184 80 / 0.1); }
.outcomes .note { margin-top: 0.3rem; color: var(--ink-2); }
.idea-place h2 { margin-top: 0.45rem; }
.place-grid { display: grid; gap: 1rem 2.5rem; }
.place-grid h3 { margin-top: 1.25rem; }
@media (min-width: 44rem) {
  .place-grid { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); }
}
@media (min-width: 62rem) {
  .split {
    grid-template-columns: minmax(0, 1.65fr) minmax(19rem, 1fr);
    grid-template-areas: "main side" "place side";
    align-items: start;
  }
}

/* ---- Plans -------------------------------------------------------------------------------- */
.month-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.75rem; margin-bottom: 1rem; }
.month-head h2 { margin: 0; font-size: 1.6rem; font-weight: 700; letter-spacing: -0.025em; }
.month-nav { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0; }
.month-nav .button { min-height: 2.4rem; padding: 0.45rem 0.85rem; font-size: 0.9rem; }
table.month { width: 100%; table-layout: fixed; border-collapse: separate; border-spacing: 0; padding: 0.35rem; overflow: hidden; }
table.month th { padding: 0.5rem 0.55rem 0.7rem; text-align: left; font: 500 0.72rem/1 var(--mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--dim); }
table.month td { height: 7.25rem; padding: 0.45rem; vertical-align: top; border-top: 1px solid var(--line); border-right: 1px solid var(--line); }
table.month td:last-child { border-right: 0; }
table.month td:nth-child(n + 6) { background: rgb(255 255 255 / 0.015); }
table.month td.outside { background: rgb(0 0 0 / 0.22); }
table.month time { display: inline-grid; place-items: center; width: 1.9rem; height: 1.9rem; font-size: 0.88rem; font-weight: 600; color: var(--ink-2); border-radius: 50%; font-variant-numeric: tabular-nums; }
table.month td.outside time { color: var(--faint); font-weight: 400; }
table.month td.today { background: rgb(255 184 80 / 0.05); }
table.month td.today time { color: var(--on-bright); background: var(--amber); box-shadow: 0 0 18px -2px rgb(255 184 80 / 0.65); }
.event {
  margin-top: 0.3rem;
  padding: 0.28rem 0.45rem;
  font-size: 0.78rem;
  font-weight: 500;
  line-height: 1.3;
  color: var(--ink);
  background: rgb(108 212 255 / 0.12);
  border-left: 2px solid var(--cyan);
  border-radius: 6px;
  overflow-wrap: anywhere;
}
.event a { color: inherit; text-decoration: none; }
.event a:hover { color: var(--cyan); }
.event small { display: block; font: 0.72rem/1.3 var(--mono); color: var(--dim); }
.event.from-google { background: transparent; border: 1px dashed var(--line-2); border-left: 2px solid var(--dim); }
.month-list { display: none; }
.month-list .event { display: inline-block; margin: 0.35rem 0.4rem 0 0; }
.month-list li.today strong { color: var(--amber); }
/* Seven columns do not fit a phone; the busy days as a list do. */
@media (max-width: 40rem) {
  table.month { display: none; }
  .month-list { display: block; }
}

/* ---- Things to do ------------------------------------------------------------------------- */
.tasks { grid-template-columns: repeat(auto-fill, minmax(min(100%, 26rem), 1fr)); align-items: start; }
.task { gap: 0.55rem; }
.task > p { margin: 0; }
.task-head { display: flex; align-items: flex-start; gap: 0.8rem; }
.task-box {
  display: grid;
  place-items: center;
  flex: none;
  width: 1.4rem;
  height: 1.4rem;
  margin-top: 0.12rem;
  color: var(--on-bright);
  border: 2px solid var(--edge);
  border-radius: 7px;
}
.task-box .icon { width: 0.9rem; height: 0.9rem; stroke-width: 3; }
.task-done .task-box { background: var(--green); border-color: var(--green); box-shadow: 0 0 14px -4px rgb(109 255 156 / 0.8); }
.task-cancelled .task-box { color: var(--dim); }
.task h2 .muted { font: 0.8rem var(--mono); }
.task-done h2, .task-cancelled h2 { color: var(--dim); text-decoration: line-through; text-decoration-color: var(--edge); }
.reminder { font-size: 0.875rem; font-weight: 500; color: var(--amber); }
.reminder .icon { width: 1rem; height: 1rem; }
.task details { margin-top: 0.2rem; }

/* ---- Family ------------------------------------------------------------------------------- */
.people > li { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 0.1rem 1rem; align-items: center; }
.people > li.empty { display: flex; }
.knocks .actions.end { align-self: start; margin-top: 1.7rem; }
.people .avatar { grid-row: 1 / span 2; width: 2.75rem; height: 2.75rem; font-size: 1.1rem; color: var(--on-bright); background: var(--amber); }
.people .avatar.role-kid { background: var(--pink); }
.people > li > .muted { grid-column: 2; font-size: 0.875rem; }
.people > li > .button { grid-column: 3; grid-row: 1 / span 2; min-height: 2.4rem; padding: 0.45rem 0.85rem; font-size: 0.9rem; }
.people > li.off .avatar { color: var(--dim); background: var(--surface-3); }
.people > li.off .person strong { color: var(--dim); }
.person { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.person strong { font-size: 1.05rem; font-weight: 600; }

/* ---- Status ------------------------------------------------------------------------------- */
.monitors { display: grid; gap: 1.25rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr)); margin-bottom: 1.25rem; }
.monitors > .panel { margin: 0; }
.lights > li { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 0.8rem; align-items: start; }
.lights strong { font-weight: 600; }
.lights .muted { font-size: 0.9rem; }
.lights .inline-action { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.8rem; margin-top: 0.5rem; }
/* Lit, dark, or half lit: the shape says it as well as the colour. */
.light { width: 0.62rem; height: 0.62rem; margin-top: 0.48rem; border-radius: 50%; }
.light.on { background: var(--green); box-shadow: 0 0 8px var(--green), 0 0 18px rgb(109 255 156 / 0.45); animation: breathe 3.2s ease-in-out infinite; }
.light.off { border: 2px solid var(--red); }
.light.part { border: 2px solid var(--amber); background: linear-gradient(90deg, var(--amber) 50%, transparent 50%); }

/* The day's spend, on a green screen that turns amber near the limit, as the other monitors of
   the time were, and red past it. Beside it, the same in words. */
.spend-now { display: grid; gap: 1rem 2rem; align-items: center; margin: 0.25rem 0 1.25rem; }
.spend-now > p { margin: 0; }
@media (min-width: 52rem) { .spend-now { grid-template-columns: minmax(0, 26rem) minmax(0, 1fr); } }
.readout.near { --phosphor: var(--amber); }
.readout.over { --phosphor: var(--red); --phosphor-dim: color-mix(in srgb, var(--phosphor) 80%, #07120c); }
.readout .crt-tube { padding: 0.95rem 1.25rem 1.05rem; }
.readout-label, .readout-of { font-size: 1.25rem; }
.readout .readout-figure { margin: 0.1rem 0 0.2rem; font-size: 3.75rem; line-height: 0.95; }
.readout-bar { font-size: 1.45rem; white-space: nowrap; }
.spend .tables { display: grid; gap: 1.5rem 2rem; margin: 1.5rem 0; grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); }
.spend > .scroll { margin-top: 0.5rem; }
.trouble { --accent: var(--amber); border-color: rgb(255 184 80 / 0.3); }

/* ---- Settings ----------------------------------------------------------------------------- */
/* /settings is a card to each page of settings (web/fields.py, SECTIONS): its icon on a quiet
   tile, how it stands in a line or two, and an arrow. One that needs a look says so, in words, in
   amber. The tiles do not glow: nine lit tiles would light nothing. */
.section-cards {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 21rem), 1fr));
  list-style: none;
  margin: 0 0 1.5rem;
  padding: 0;
}
.section-cards > li { display: flex; }
.section-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 0.95rem;
  align-items: start;
  width: 100%;
  margin: 0;
  color: var(--ink);
  text-decoration: none;
  transition: border-color var(--afterglow), background-color 0.2s;
}
.section-card:hover { background: var(--surface-2); border-color: rgb(109 255 156 / 0.4); transition-duration: var(--glow-in), 0.15s; }
.section-card.look { border-color: rgb(255 184 80 / 0.35); }
.section-card.look:hover { border-color: rgb(255 184 80 / 0.65); }
.section-icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 2.6rem;
  height: 2.6rem;
  color: var(--accent);
  background: var(--surface-3);
  border: 1px solid var(--line-2);
  border-radius: 13px;
}
.section-icon .icon { width: 1.3rem; height: 1.3rem; }
.section-what { display: grid; gap: 0.2rem; min-width: 0; }
.section-what strong { font-size: 1.05rem; font-weight: 600; line-height: 1.35; }
.section-state { font-size: 0.9rem; line-height: 1.45; color: var(--dim); overflow-wrap: anywhere; }
.section-what .tag { justify-self: start; margin-top: 0.35rem; }
.section-card .go { align-self: center; color: var(--dim); transition: transform 0.15s, color 0.15s; }
.section-card:hover .go { color: var(--accent); transform: translateX(2px); }

/* A page of settings: the others down the side where there is room, and the page beside them.
   On a narrower screen the way to the others is Settings, above the title. */
.settings-layout { display: grid; gap: 1.5rem; }
.settings-body { min-width: 0; }
.settings-nav { display: none; }
.settings-nav ol { display: grid; gap: 0.15rem; list-style: none; margin: 0; padding: 0; }
.settings-nav a {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.5rem 0.7rem;
  font-size: 0.92rem;
  font-weight: 500;
  line-height: 1.3;
  color: var(--ink-2);
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: 10px;
  transition: background-color 0.15s, color 0.15s;
}
.settings-nav a:hover { color: var(--ink); background: var(--surface-2); }
.settings-nav .icon { width: 1.05rem; height: 1.05rem; color: var(--dim); }
.settings-nav a[aria-current="page"] { color: var(--ink); background: var(--surface-2); border-color: var(--line-2); }
.settings-nav a[aria-current="page"] .icon { color: var(--accent); }
@media (min-width: 62rem) {
  .settings-layout { grid-template-columns: 14.5rem minmax(0, 1fr); align-items: start; }
  .settings-nav { display: block; position: sticky; top: 5.25rem; }
}

/* Numbered steps, as in the guide to giving the page a name, and a command to copy. */
ol.steps { display: grid; gap: 0.9rem; margin: 1rem 0 0; padding-left: 1.3rem; }
ol.steps li { padding-left: 0.2rem; }
pre.command { margin: 0.5rem 0; padding: 0.7rem 0.85rem; overflow-x: auto; font: 0.85rem/1.5 var(--mono); background: var(--field); border: 1px solid var(--line); border-radius: var(--r-sm); }

/* The status page's recent activity: each line a link to its history, whole-row to tap. */
.activity li + li { border-top: 1px solid var(--line); }
.activity a { display: grid; gap: 0.2rem; padding: 0.65rem 0.2rem; color: var(--ink); text-decoration: none; border-radius: var(--r-sm); }
.activity a:hover { background: var(--surface-2); }
.activity-title { font-weight: 550; overflow-wrap: anywhere; }
pre.json { max-height: 24rem; overflow: auto; padding: 0.75rem; font: 0.8rem/1.45 var(--mono); white-space: pre-wrap; overflow-wrap: anywhere; background: var(--field); border: 1px solid var(--line); border-radius: var(--r-sm); }
.tool-calls li + li { margin-top: 0.4rem; }

/* What needs an admin, first on the status page: edged in red, which is kept for what went wrong. */
.attention { margin-bottom: 1.25rem; border-color: color-mix(in srgb, var(--red) 45%, var(--line)); }
.attention h2 .icon { color: var(--red); }

/* A list to choose from, with a box under it for another, shown only while "Another" is chosen.
   A browser without :has() drops the rule and shows the box always, which still works. */
.pick { display: grid; gap: 0.55rem; }
.pick .another { display: grid; gap: 0.35rem; }
.pick .another label { color: var(--dim); font-size: 0.85rem; font-weight: 500; }
.pick:not(:has(option[value="another"]:checked)) .another { display: none; }

/* Boxes two or three to a row where they fit, wide enough for "Default (the company that
   answers)": squeezed narrower, the part in brackets, the part worth reading, would be cut off. */
.grid { display: grid; gap: 1.25rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr)); }
.setting { min-width: 0; }
.setting + .setting { margin-top: 1.1rem; }
.grid .setting + .setting { margin-top: 0; }
.setting.bad input, .setting.bad select { border-color: var(--red); }
/* A box's label, and beside it whether the family changed it here: an empty box is the default. */
.setting-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0 0.75rem; }
.changed {
  padding: 0.12rem 0.45rem 0.1rem;
  font: 500 0.68rem/1.3 var(--mono);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--green);
  background: rgb(109 255 156 / 0.1);
  border-radius: 999px;
}
.key-state { font-size: 0.8rem; color: var(--dim); }
.setting .check { margin-top: 0.5rem; }
/* Fine-tuning, folded away: the heading is the thing to click, and says how much was changed. */
.fold > summary { align-items: center; gap: 0.6rem; }
.fold > summary .changed { margin-left: auto; }
.more > summary .changed { margin-left: 0.5rem; }
/* A word before the boxes: what has been spent, or what is missing before they can do anything. */
.notice { display: flex; align-items: flex-start; gap: 0.75rem; }
.notice > .icon { flex: none; margin-top: 0.2rem; color: var(--amber); }
.notice.spent > .icon { color: var(--accent); }
.state-line { margin: 0 0 1rem; color: var(--ink-2); }
/* Each page's Save stays in reach while its form is on screen, with what an empty box means. */
.save-bar {
  position: sticky;
  bottom: 1rem;
  z-index: 5;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1rem;
  margin: 0 0 1.25rem;
  padding: 0.65rem 0.65rem 0.65rem 1.1rem;
  background: rgb(18 22 21 / 0.9);
  border: 1px solid var(--line-2);
  border-radius: var(--r-lg);
  box-shadow: 0 -8px 30px rgb(0 0 0 / 0.45);
}
.save-bar p { margin: 0; font-size: 0.875rem; }
.save-bar button { margin: 0 0 0 auto; }
@supports (backdrop-filter: blur(1px)) { .save-bar { backdrop-filter: blur(14px); } }
@media (max-width: 51.99rem) {
  .save-bar { bottom: calc(var(--tab-h) + 0.75rem + env(safe-area-inset-bottom)); }
}
/* On a phone the bar is only Save, so it stays one row above the tabs; each dropdown still says
   what its default is. A bar that shares its page with another form's button stays still. */
@media (max-width: 30rem) { .save-bar p { display: none; } }
.save-bar.still { position: static; box-shadow: none; }
.revealed {
  margin: 0.75rem 0 0;
  padding: 0.55rem 0.75rem;
  background: var(--field);
  border: 1px dashed var(--amber);
  border-radius: var(--r-sm);
  overflow-wrap: anywhere;
}
/* Her own description has changed since the family rewrote her: said above their rewrite, with
   what changed folded away under it. That is a line diff in the machine's small voice, and each
   line keeps its + or -, so the difference never rests on colour: a new line is lit in the
   page's colour, one that has gone is quiet, and the rest are as they were. Kept to .drift: the
   history of changes on the settings pages is a list called .changes too. */
.drift { margin: 0 0 0.9rem; }
.drift > .hint { margin: 0 0 0.3rem; }
.drift .changes {
  max-height: 24rem;
  margin: 0.6rem 0 0;
  padding: 0.55rem 0;
  overflow: auto;
  font: 0.82rem/1.6 var(--mono);
  color: var(--ink-2);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  background: var(--field);
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
}
.drift .changes > span { display: block; padding: 0 0.8rem; border-left: 3px solid transparent; }
.drift .changes > .added { color: var(--ink); background: color-mix(in srgb, var(--accent) 9%, transparent); border-left-color: var(--accent); }
.drift .changes > .removed { color: var(--dim); background: rgb(255 255 255 / 0.025); border-left-color: var(--edge); }
/* How one of her lines reads now, under the box that writes it: each of its wordings filled in
   with made-up details, as the family would get it. Quieter than the box above, which is what is
   being written, and joined by a rule down the left as the one line they are. */
.reads { margin: 0.7rem 0 0; }
.reads > ul { display: grid; gap: 0.3rem; margin: 0.35rem 0 0; padding: 0; list-style: none; }
.reads li { padding: 0.05rem 0 0.05rem 0.75rem; font-size: 0.92rem; color: var(--ink-2); border-left: 2px solid var(--line-2); overflow-wrap: anywhere; }
#google fieldset { display: grid; gap: 0.5rem; margin: 0 0 0.9rem; }
#google > .more:last-child { margin-top: 1.25rem; padding-top: 1rem; border-top: 1px solid var(--line); }
#google textarea { font: 0.88rem/1.5 var(--mono); }
.steps { display: grid; gap: 0.6rem; padding-left: 1.4rem; }
.steps li::marker { color: var(--green); font-weight: 600; }
/* Her lines on the Personality page, a group under each small heading. */
.lines { display: grid; gap: 1.1rem; margin-bottom: 0.5rem; }
.lines .setting + .setting { margin-top: 0; }
.lines textarea { min-height: 0; }
#lines h3 { display: flex; align-items: center; gap: 0.6rem; margin-top: 1.75rem; }
#lines .more { margin-top: 1.5rem; }
.changes strong { margin-right: 0.3rem; font-weight: 600; }

/* ---- Setting up ---------------------------------------------------------------------------- */
/* One step at a time (web/setup.py): a row of numbered steps saying where you are, the step's
   title and what it is for, what to do, and the way on. Numbers are in the machine's voice, and
   the step you are on is lit. */
.step-head { margin: 0 0 1.1rem; }
.step-head .eyebrow { display: block; margin-bottom: 0.6rem; color: var(--green); }
.step-head h1 { margin: 0; }
.lead, .why { max-width: 60ch; margin: 0 0 1.25rem; font-size: 1.05rem; color: var(--ink-2); }
/* Both are <nav>, and the bar's own nav rules are written for the bar; these are not in it. */
.setup-progress, .step-nav { margin-left: 0; }
.setup-progress ol { display: flex; flex-wrap: wrap; gap: 0.4rem; list-style: none; margin: 0 0 1.75rem; padding: 0; }
.setup-progress a {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.25rem 0.75rem 0.25rem 0.25rem;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--dim);
  text-decoration: none;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 999px;
  transition: border-color var(--afterglow), color 0.15s;
}
.setup-progress a:hover { color: var(--ink); border-color: var(--edge); transition-duration: var(--glow-in), 0.15s; }
.setup-progress a > span[aria-hidden] {
  display: inline-grid;
  place-items: center;
  width: 1.6rem;
  height: 1.6rem;
  font: 500 0.78rem/1 var(--mono);
  color: var(--ink-2);
  background: var(--surface-3);
  border-radius: 50%;
}
.setup-progress .done a > span[aria-hidden] { color: var(--green); background: rgb(109 255 156 / 0.12); }
.setup-progress a[aria-current="step"] {
  color: var(--ink);
  font-weight: 600;
  border-color: rgb(109 255 156 / 0.55);
  box-shadow: 0 0 22px -10px rgb(109 255 156 / 0.7);
}
.setup-progress a[aria-current="step"] > span[aria-hidden] { color: var(--on-bright); background: var(--green); box-shadow: 0 0 10px rgb(109 255 156 / 0.5); }
/* A step that is done says so, lit. */
.state.done {
  margin: 0 0 1.25rem;
  padding: 0.75rem 1rem;
  color: var(--green);
  background: rgb(109 255 156 / 0.07);
  border: 1px solid rgb(109 255 156 / 0.28);
  border-radius: var(--r);
}
.step-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin: 2rem 0 0.75rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--line);
}
.step-skip-note { max-width: 60ch; font-size: 0.9rem; }
.tips { display: grid; gap: 0.4rem; margin: 0 0 1.25rem; padding-left: 1.2rem; color: var(--ink-2); }
.tips li::marker { color: var(--green); }
/* The AI companies, as cards to choose between; the chosen one is lit. */
.choices { display: grid; gap: 0.85rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr)); margin: 0 0 1.25rem; }
.choice {
  display: grid;
  gap: 0.3rem;
  align-content: start;
  padding: 0.9rem 1rem;
  color: var(--ink);
  text-decoration: none;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
  transition: border-color var(--afterglow), box-shadow var(--afterglow);
}
.choice:hover { border-color: rgb(109 255 156 / 0.45); transition-duration: var(--glow-in); }
.choice.chosen { border-color: var(--green); box-shadow: var(--shadow), 0 0 0 1px var(--green), 0 0 30px -12px rgb(109 255 156 / 0.6); }
.choice strong { display: flex; flex-wrap: wrap; align-items: center; gap: 0.45rem; font-weight: 600; }
.choice .muted { font-size: 0.9rem; }
/* The steps on the overview: a number that turns to a tick, what the step is, and whether it is
   needed. */
.setup-list { display: grid; gap: 0.6rem; list-style: none; margin: 0 0 1.5rem; padding: 0; }
.setup-list > li.panel { margin: 0; padding: 0; }
.setup-list a {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 0.9rem;
  align-items: center;
  padding: 0.85rem 1.1rem;
  color: var(--ink);
  text-decoration: none;
  border-radius: inherit;
  transition: background-color 0.15s;
}
.setup-list a:hover { background: var(--surface-2); }
.setup-list a:hover strong { color: var(--green); }
.setup-list .number {
  display: inline-grid;
  place-items: center;
  width: 2.1rem;
  height: 2.1rem;
  font: 500 0.9rem/1 var(--mono);
  color: var(--ink-2);
  background: var(--surface-3);
  border: 1px solid var(--line-2);
  border-radius: 50%;
}
.setup-list .done .number { color: var(--green); background: rgb(109 255 156 / 0.12); border-color: rgb(109 255 156 / 0.35); }
.setup-list .what { display: grid; min-width: 0; }
.setup-list .what strong { font-weight: 600; }
.setup-list .what .muted { font-size: 0.9rem; overflow-wrap: anywhere; }
.tag.need-needed { color: var(--amber); background: rgb(255 184 80 / 0.1); }
.tag.need-recommended, .tag.need-done { color: var(--green); background: rgb(109 255 156 / 0.1); }
/* The family step lists people without faces, one to a line. */
.people > li:not(:has(> .avatar)) { grid-template-columns: minmax(0, 1fr); }
.people > li:not(:has(> .avatar)) > .muted { grid-column: 1; }
.knocks .knock { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem 1rem; }
.knocks .knock form { margin: 0; }
.calendars { display: grid; gap: 0.35rem; margin: 0 0 0.9rem; padding: 0.6rem 0.8rem; background: var(--field); border: 1px solid var(--line-2); border-radius: var(--r-sm); }
.roles { margin-top: 1rem; font-size: 0.92rem; }
.steps .button { min-height: 2.25rem; padding: 0.35rem 0.8rem; font-size: 0.9rem; }
/* On a phone the row of steps is numbers only, but for the one you are on; the names stay there
   for a screen reader. */
@media (max-width: 40rem) {
  .setup-progress ol { gap: 0.3rem; }
  .setup-progress a { padding-right: 0.25rem; }
  .setup-progress a[aria-current="step"] { padding-right: 0.75rem; }
  .setup-progress a:not([aria-current="step"]) .label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

/* ---- What she remembers -------------------------------------------------------------------- */
.memories > li { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem; }
.memory-fact { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.4rem; margin: 0; }
.memory-source { margin: 0.3rem 0 0; }
.memory form { flex: none; margin: 0; }
.memories > li.gone { display: block; }
.memory.ended .memory-fact strong, .memory.gone .memory-fact span { color: var(--dim); }

/* ---- Sign in, and nowhere ----------------------------------------------------------------- */
.page-signin .places, .page-signin .tools { display: none; }
.page-signin main, .page-lost main { display: grid; align-content: center; }
.signin { width: 100%; padding: 1.5rem clamp(1.25rem, 5vw, 2.25rem) 2.25rem; }
/* The mark's face, awake on a green screen: it blinks now and then. */
.signin .crt { margin: 0 0 1.75rem; }
.signin .crt-tube { display: grid; justify-items: center; padding: 1.6rem 1.2rem 1.1rem; }
.crt .crt-face { display: block; width: 8.5rem; height: auto; overflow: visible; filter: blur(0.35px) drop-shadow(0 0 5px color-mix(in srgb, var(--phosphor) 60%, transparent)); }
.crt-face path { fill: none; stroke: var(--phosphor); stroke-width: 3.2; stroke-linecap: round; }
.crt-face .eye { transform-box: fill-box; transform-origin: center; animation: eyes 7s ease-in-out infinite; }
.signin .signin-ready { justify-self: start; margin-top: 1.1rem; }
.signin h1 { margin: 0 0 1.5rem; font-size: 1.75rem; }
.signin input + label { margin-top: 1rem; }
.signin form button { width: 100%; }

.lost { width: 100%; max-width: 30rem; margin: 0 auto; text-align: center; }
/* A radar console on a green screen: an empty scope, still sweeping, with 404 (or 403) on its
   face, and beside it what the console makes of that. */
.lost .crt { margin: 0 0 2rem; text-align: left; }
.lost .crt-tube { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); gap: 1rem; align-items: center; }
.lost .radar { width: 100%; }
.lost .radar-label { display: none; }
.lost-readout { display: grid; gap: 0.15rem; font-size: 1.3rem; line-height: 1.1; }
.lost-readout .gap { margin-top: 0.8rem; }
.lost .eyebrow { justify-content: center; }
.lost h1 { margin: 0.45rem 0 0.5rem; }
.lost .button { margin-top: 1rem; }

/* ---- The foot ----------------------------------------------------------------------------- */
.foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1.5rem;
  width: 100%;
  max-width: 74rem;
  margin: 0 auto;
  padding: 1.5rem clamp(1rem, 3vw, 2rem) 2rem;
  font-size: 0.875rem;
  color: var(--dim);
  border-top: 1px solid var(--line);
}
.foot-mark { font: 500 0.9rem/1 var(--mono); color: var(--ink-2); }
.foot-mark .icon { width: 1.15rem; height: 1.15rem; color: var(--green); filter: drop-shadow(0 0 3px rgb(109 255 156 / 0.6)); }
/* The copyright and version on a line of their own, in the machine's small voice, like the banner
   an old machine printed as it started. */
.foot .legal { flex-basis: 100%; margin: 0; font: 0.72rem/1.5 var(--mono); letter-spacing: 0.02em; color: var(--faint); }
@media (max-width: 40rem) { .foot { justify-content: center; text-align: center; } }

/* ---- Motion ------------------------------------------------------------------------------- */
@keyframes blink { 50% { opacity: 0; } }
@keyframes breathe { 50% { opacity: 0.55; } }
/* The glyphs on her screen falling a row at a time, as a character display moved them, through
   the sixteen rows of the pattern and round again. */
@keyframes fall { from { transform: translateY(-13.6em); } to { transform: none; } }
/* Every few seconds the 404 or 403 catches, like a tube losing its picture for an instant. */
@keyframes flicker { 0%, 91%, 94%, 100% { opacity: 1; } 92% { opacity: 0.55; } 93% { opacity: 0.9; } }
/* The radar's sweep, and the flare and fade of a blip as it passes, on the same clock. */
@keyframes sweep { to { transform: rotate(1turn); } }
@keyframes blip { 0% { opacity: 1; } 62%, 100% { opacity: var(--rest, 0.3); } }
@keyframes ping { 0% { opacity: 0.9; transform: scale(1); } 32%, 100% { opacity: 0; transform: scale(3.6); } }
@keyframes power-on {
  0% { opacity: 0; transform: scale(1, 0.01); }
  30% { opacity: 1; transform: scale(1, 0.01); }
  65% { transform: scale(1, 1.03); }
  100% { opacity: 1; transform: none; }
}
@keyframes eyes { 0%, 92%, 100% { transform: none; } 94%, 96% { transform: scaleY(0.12); } }
/* The glow starts from the card's own shadow, so the two can blend: shadows fade into each other
   only when they line up, inset with inset. */
@keyframes landed { from { box-shadow: var(--shadow), 0 0 0 1px rgb(109 255 156 / 0.65), 0 0 40px -6px rgb(109 255 156 / 0.55); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* ---- Other ways of seeing ----------------------------------------------------------------- */
@media (prefers-contrast: more) {
  :root { --ink-2: #dde4e0; --dim: #c3ccc7; --faint: #a7b2ac; --line: #3a4541; --line-2: #56625c; --edge: #9fb0a6; }
  .welcome::before, .radar::after, .crt-tube::before, .crt-tube::after { display: none; }
  .glow, .radar-say, .chip-day, .crt-tube, .crt .dim { text-shadow: none; }
  button, .button, .title-icon, .brand-mark, .chip, .task-done .task-box, .radar,
  .welcome .ask, .presence, .title-icon.presence, .section-icon.presence { box-shadow: none; }
  .presence-glass { -webkit-mask-image: none; mask-image: none; }
  .presence-glass::before, .presence-glass::after { filter: none; text-shadow: none; }
  .icon, .brand-mark .icon, .title-icon .icon, .foot-mark .icon, .radar svg, .radar-say,
  .crt-tube > *, .crt .crt-face { filter: none; }
  .title-icon { background: color-mix(in srgb, var(--accent) 12%, transparent); }
}
@media (forced-colors: active) {
  .light, .task-box, .chip, .avatar, .title-icon { forced-color-adjust: none; border: 2px solid CanvasText; }
  .title-icon { background: none; }
  .caret { background: CanvasText; }
  /* Her screen is an empty one: outlined, and nothing on it. */
  .presence, .title-icon.presence, .section-icon.presence { background: none; box-shadow: none; }
  .presence-glass { display: none; }
  .glyph.presence { forced-color-adjust: none; border: 2px solid CanvasText; }
  /* The tick a box would make shows only when pointed at, as it does in colour. */
  button.tick .icon { visibility: hidden; }
  button.tick:hover .icon, button.tick:focus-visible .icon { visibility: visible; }
  /* A screen that is only a picture goes; one with words on it keeps them, plainly. */
  .crt[aria-hidden="true"], .radar, .crt::after, .crt-tube::before, .crt-tube::after { display: none; }
  .crt, .crt-tube { border: 1px solid CanvasText; box-shadow: none; }
  .crt-tube > * { filter: none; }
}

/* On paper the page turns into green-bar printout: black on white, a pale green band on every
   other line, which is how a month of plans goes on the fridge. */
@media print {
  /* Continuous paper came with tractor-feed holes down both edges, torn off along a perforation. */
  body { padding-inline: 0.55in; }
  body::before, body::after {
    content: "";
    position: fixed;
    top: 0;
    bottom: 0;
    width: 0.42in;
    background: radial-gradient(circle, #e4e4e4 0 0.07in, #c9c9c9 0.075in 0.082in, transparent 0.086in) center 0.12in / 0.42in 0.5in repeat-y;
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }
  body::before { left: 0; border-right: 1px dashed #bdbdbd; }
  body::after { right: 0; border-left: 1px dashed #bdbdbd; }
  :root { --ink: #111; --ink-2: #222; --dim: #3b5a44; --accent: #0b5a2a; --cyan: #0b5a2a; --green: #0b5a2a; --line: #9fcca9; --line-2: #7fb58c; }
  html, body { background: #fff !important; color: #111; }
  .bar, .skip, .foot, .page-actions, .tabs, .month-nav, .ask, form, details:not([open]), .actions,
  .save-bar, .title-icon, .radar, .crt[aria-hidden="true"], .crt::after, .crt-tube::before,
  .crt-tube::after, .starters, .brief-more, .presence-glass { display: none !important; }
  main { max-width: none; padding: 0; }
  .panel, .welcome, .chip, .bubble, .crt, .crt-tube {
    background: none !important;
    box-shadow: none !important;
    border-color: var(--line) !important;
    break-inside: avoid;
  }
  .welcome::before { display: none; }
  .glow, .chip-day { color: #0b5a2a; text-shadow: none; }
  .crt-tube { color: #111; text-shadow: none; }
  .crt-tube > * { filter: none; }
  a { color: inherit; text-decoration: none; }
  .agenda > li:nth-child(odd), .plain > li:nth-child(odd), .data tr:nth-child(odd) td,
  table.month tr:nth-child(odd) td {
    background: #e2f2e4 !important;
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }
  table.month { display: table !important; }
  .month-list { display: none !important; }
  table.month td { height: 6rem; border-color: var(--line); }
  table.month td.today time { background: none; color: #111; box-shadow: none; outline: 1px solid #111; }
  .event { background: none; border-left-color: #0b5a2a; }
}

/* The kids' wish lists (docs/WISHES.md). Her order is the point, so each card leads with its
   number; the buttons that move it are big enough for a finger on an iPad. */
.wish-lists { display: grid; gap: 1.25rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); }
.wish-list h3 { display: flex; align-items: center; gap: 0.4rem; margin: 0; }
.wishes { list-style: none; margin: 0.5rem 0 0; padding: 0; display: grid; gap: 0.6rem; }
.wish-line { display: flex; align-items: baseline; gap: 0.6rem; }
.wish-rank { color: var(--accent); font-weight: 700; min-width: 1.5rem; }
.wish-actions { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-top: 0.5rem; }
.wish-actions form, .wish-inline { display: inline-flex; align-items: center; gap: 0.35rem; margin: 0; }
.wish-actions button, .wish-inline button, .wish-actions select { min-height: 44px; }
.wish-answer { margin-top: 0.6rem; }
.wish-add { margin-bottom: 1rem; }
.wish-kid + .wish-kid { margin-top: 2rem; }
.wish-top { margin: 0.4rem 0 0; }
/* With wishes.js running, the number is a handle to drag the card by; only the handle stops
   the page from scrolling under a finger. */
.can-drag .wish-rank { cursor: grab; touch-action: none; min-width: 44px; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }
.wish.dragging { opacity: 0.6; outline: 2px dashed var(--accent); }
.home-wishes { --accent: var(--pink); margin-bottom: 1.25rem; }
.home-wishes h3 { font-size: 1rem; margin: 0.25rem 0; }

/* Speaking instead of typing (dictate.js): a round mic beside each box that takes words, drawn
   only where the browser can write speech down. Listening, it lights up green and its ring
   breathes; the words land in the box as they are said. At least 44px, for a finger. */
button.mic {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 2.75rem;
  height: 2.75rem;
  min-height: 2.75rem;
  padding: 0;
  color: var(--ink-2);
  background: var(--surface-2);
  border: 1px solid var(--line-2);
  border-radius: 50%;
  box-shadow: none;
}
button.mic:hover { color: var(--ink); border-color: var(--edge); background: var(--surface-3); box-shadow: none; }
button.mic .icon { width: 1.2rem; height: 1.2rem; }
button.mic.listening {
  color: var(--bg);
  background: var(--green);
  border-color: transparent;
  box-shadow: 0 0 0 4px rgb(109 255 156 / 0.18), 0 0 22px -4px rgb(109 255 156 / 0.7);
  animation: listening 1.4s ease-in-out infinite;
}
@keyframes listening {
  50% { box-shadow: 0 0 0 8px rgb(109 255 156 / 0.08), 0 0 22px -4px rgb(109 255 156 / 0.7); }
}
@media (prefers-reduced-motion: reduce) {
  button.mic.listening { animation: none; }
}
/* In the box, beside Send. */
.ask .mic-slot { display: inline-flex; margin-left: auto; }
.ask .mic-slot:empty { display: none; }
.ask .mic-slot:not(:empty) + .send { margin-left: 0; }
/* Anywhere else, inside the right-hand end of the box it fills. */
.field.can-dictate { position: relative; }
.field.can-dictate > [data-dictate] { padding-right: 3.4rem; }
.field.can-dictate > button.mic { position: absolute; right: 0.35rem; bottom: 0.35rem; width: 2.25rem; height: 2.25rem; min-height: 2.25rem; border-color: transparent; background: transparent; }
.field.can-dictate > button.mic.listening { background: var(--green); }

/* The Status tile's light, for an admin (web/status.light): a mark in the icon's corner, amber ▲
   while something needs a look, red ■ while the family cannot be answered. Shape and word as
   well as colour, so it never says anything by colour alone. */
.tools > a.lit { position: relative; }
.tools > a.lit .light {
  position: absolute;
  top: 0.05rem;
  right: -0.2rem;
  display: grid;
  place-items: center;
  width: 0.8rem;
  height: 0.8rem;
  font-size: 0.45rem;
  font-weight: 700;
  line-height: 1;
  color: var(--bg);
  border: 2px solid var(--bg);
  border-radius: 50%;
  box-sizing: content-box;
}
.tools > a.lit-warn .icon { color: var(--amber); }
.tools > a.lit-warn .light { background: var(--amber); }
.tools > a.lit-bad .icon { color: var(--red); }
.tools > a.lit-bad .light { background: var(--red); }
