/* ===========================================================================
   Personal CRM — component layer.

   Built only from the tokens in tokens.css. No raw hex, no arbitrary px: if
   something needs a value that isn't a token, the token set is wrong. Still
   one hand-written stylesheet, still no build step.
   =========================================================================== */

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: 400 var(--fs-body)/var(--lh-body) var(--font-ui);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* The logo's 45° geometry, ghosted into the page at brand opacity. Fixed and
   non-repeating — the guide forbids tiling it. */
body::before {
  content: "";
  position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background-image: repeating-linear-gradient(
    45deg,
    transparent 0 64px,
    currentColor 64px 66px,
    transparent 66px 150px);
  opacity: .022;
}

a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px;
    text-decoration-thickness: 1px; }
a:hover { text-decoration-thickness: 2px; }

/* Prose keeps its underlines. Dense UI does not: a table of eight names is
   eight blue rules, which reads as noise rather than as emphasis. The link
   affordance comes from colour and position instead, and the underline
   returns on hover at the brand's 2px. */
ul.list a:not(.pill), ul.timeline a:not(.pill), .grid a, .facts a {
  text-decoration: none;
}
ul.list a:not(.pill):hover, ul.timeline a:not(.pill):hover,
.grid a:hover, .facts a:hover {
  text-decoration: underline; text-decoration-thickness: 2px;
}

:where(a, button, input, select, textarea, summary):focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
  border-radius: var(--radius-sm);
}

hr { border: 0; border-top: 1px solid var(--border); margin: var(--space-6) 0; }

/* --------------------------------------------------------------------------
   LAYOUT
   -------------------------------------------------------------------------- */
.wrap { width: 100%; max-width: 1140px; margin: 0 auto; padding: 0 var(--space-6); }

main.wrap { padding-top: var(--space-8); padding-bottom: var(--space-20); }

/* The login screen: one narrow column, centred, with room above it. Its own
   page rather than the app shell, so it carries no nav to pages you cannot
   reach yet. */
main.auth { max-width: 24rem; padding-top: var(--space-16); }
main.auth .brand { margin-bottom: var(--space-8); }

/* Asymmetric by default, per the brand: a wide main column, a narrower rail. */
.split { display: grid; grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr);
         gap: var(--space-6); align-items: start; }
.cols  { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
         gap: var(--space-6); align-items: start; }
.stack-col { display: flex; flex-direction: column; gap: var(--space-6); }

@media (max-width: 940px) {
  .split, .cols { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 600px) {
  .wrap { padding: 0 var(--space-4); }
  .stat-row { gap: var(--space-6); }
  .page-head { gap: var(--space-4); }
}

/* --------------------------------------------------------------------------
   HEADER + NAV
   -------------------------------------------------------------------------- */
.app-header {
  position: sticky; top: 0; z-index: 20;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(20px);
  border-bottom: 1px solid var(--border);
}
/* Fallback where color-mix is unavailable — opaque rather than unreadable. */
@supports not (background: color-mix(in srgb, red 50%, blue)) {
  .app-header { background: var(--bg); }
}

.app-header .wrap {
  display: flex; align-items: center; gap: var(--space-6);
  min-height: 60px; flex-wrap: wrap;
}

.brand {
  display: inline-flex; align-items: center; gap: var(--space-2);
  text-decoration: none; color: var(--fg);
  font: 700 17px/1 var(--font-display); letter-spacing: -0.01em;
  /* Hard edges next to the mark, per the guide. */
  border-radius: 0;
}
.brand:hover { text-decoration: none; }
.brand img { width: 26px; height: 26px; display: block; }

.nav { display: flex; align-items: center; gap: var(--space-1); flex-wrap: wrap; }
.nav a {
  --_pad: var(--space-2) var(--space-3);
  padding: var(--_pad);
  color: var(--fg-muted);
  text-decoration: none;
  font: 500 var(--fs-body)/1 var(--font-ui);
  border-radius: var(--radius-md);
  position: relative;
  transition: color var(--dur-quick) var(--ease-out),
              background var(--dur-quick) var(--ease-out);
}
.nav a:hover { color: var(--fg); background: var(--ink-06); text-decoration: none; }
@media (prefers-color-scheme: dark) {
  .nav a:hover { background: rgb(255 250 248 / .07); }
}
.nav a.on { color: var(--fg); }
.nav a.on::after {
  content: ""; position: absolute; left: var(--space-3); right: var(--space-3);
  bottom: -1px; height: 2px; background: var(--accent);
}

/* --------------------------------------------------------------------------
   ACCOUNT MENU
   A person's own things — profile, tokens, sign out — under one avatar on the
   right of the bar. Built on <details>/<summary>, so it works without JS; a
   small script closes it on an outside click.
   -------------------------------------------------------------------------- */
/* width:auto and the ::before reset override the global disclosure rules
   (`details { width: 100% }` and the "›" summary marker) that otherwise make
   this stretch full-width, wrap to its own line, and show a stray caret. */
.menu { position: relative; margin-left: auto; flex: none; width: auto; margin-bottom: 0; }
.menu > summary {
  display: inline-flex; align-items: center; gap: var(--space-1);
  margin: 0;
  padding: var(--space-1) var(--space-2) var(--space-1) var(--space-1);
  border-radius: var(--radius-pill);
  cursor: pointer; list-style: none; user-select: none;
  border: 1px solid transparent;
  transition: background var(--dur-quick) var(--ease-out),
              border-color var(--dur-quick) var(--ease-out);
}
.menu > summary::-webkit-details-marker { display: none; }
.menu > summary::before { content: none; }   /* kill the global disclosure caret */
.menu > summary:hover { color: inherit; }     /* not the accent-text disclosure hover */
.menu > summary:hover { background: var(--ink-06); }
@media (prefers-color-scheme: dark) {
  .menu > summary:hover { background: rgb(255 250 248 / .07); }
}
.menu > summary:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.menu[open] > summary { background: var(--ink-06); border-color: var(--border);
                        margin-bottom: 0; }   /* override details[open] margin */

.menu .avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: var(--radius-pill);
  background: var(--accent-wash); color: var(--accent);
}
/* When the open page lives in this menu (Account or Tokens), fill the avatar. */
.menu[data-active] .avatar { background: var(--accent); color: var(--fg-on-accent); }
.menu .chev { color: var(--fg-subtle); transition: transform var(--dur-quick) var(--ease-out); }
.menu[open] .chev { transform: rotate(180deg); }

.menu-pop {
  position: absolute; right: 0; top: calc(100% + var(--space-2));
  z-index: 30; min-width: 208px;
  display: flex; flex-direction: column; gap: 2px;
  padding: var(--space-2);
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-3);
}
.menu-pop .menu-label {
  margin: 0; padding: var(--space-1) var(--space-3) var(--space-2);
  font: 500 var(--fs-small)/var(--lh-small) var(--font-ui);
  letter-spacing: var(--tr-small); text-transform: uppercase;
  color: var(--fg-subtle);
}
.menu-pop a, .menu-pop .menu-item {
  display: block; width: 100%; text-align: left;
  padding: var(--space-2) var(--space-3); border-radius: var(--radius-md);
  color: var(--fg); font: 500 var(--fs-body)/1.2 var(--font-ui);
  text-decoration: none; background: none; border: 0; cursor: pointer;
  box-shadow: none;
}
.menu-pop a:hover, .menu-pop .menu-item:hover {
  background: var(--ink-06); color: var(--fg); text-decoration: none; box-shadow: none;
}
@media (prefers-color-scheme: dark) {
  .menu-pop a:hover, .menu-pop .menu-item:hover { background: rgb(255 250 248 / .07); }
}
.menu-pop a:active, .menu-pop .menu-item:active { transform: none; }
.menu-pop a.on { color: var(--accent); background: var(--accent-wash); }
.menu-pop a.on::after { content: none; }   /* no underline bar inside the menu */
.menu-pop hr { margin: var(--space-1) 0; border: 0; border-top: 1px solid var(--border); }

/* Five tabs will not fit on a phone. Scroll them on one line rather than
   wrapping the header to double height on every page. The account menu stays
   outside this scroller, pinned right, so its dropdown is never clipped. Must
   come after the rules above: same specificity, so source order decides. */
@media (max-width: 600px) {
  .app-header .wrap { flex-wrap: nowrap; gap: var(--space-3); min-height: 56px; }
  .brand span { display: none; }   /* the mark alone carries it at this width */
  .nav { flex: 1 1 auto; min-width: 0; flex-wrap: nowrap;
         overflow-x: auto; scrollbar-width: none; }
  .nav::-webkit-scrollbar { display: none; }
}

/* --------------------------------------------------------------------------
   PAGE HEAD
   -------------------------------------------------------------------------- */
.page-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--space-6); flex-wrap: wrap;
  margin-bottom: var(--space-6);
}
.page-head h1 { margin: 0; font: 700 var(--fs-h1)/var(--lh-h1) var(--font-display);
                letter-spacing: var(--tr-h1); color: var(--fg); }
.page-head .head-actions { display: flex; align-items: center; gap: var(--space-2);
                           flex-wrap: wrap; }
.page-head .sub { font-weight: 400; color: var(--fg-muted); letter-spacing: 0; }

.lede {
  font: 400 16px/1.6 var(--font-text);
  color: var(--fg-muted);
  max-width: 64ch;
  margin: calc(var(--space-2) * -1) 0 var(--space-6);
}

/* --------------------------------------------------------------------------
   STATS
   -------------------------------------------------------------------------- */
.stat-row {
  display: flex; gap: var(--space-10); flex-wrap: wrap;
  padding-bottom: var(--space-6); margin-bottom: var(--space-6);
  border-bottom: 1px solid var(--border);
}
.stat { display: flex; flex-direction: column-reverse; gap: var(--space-1); }
.stat b { font: 700 var(--fs-h1)/1 var(--font-display); letter-spacing: -0.01em;
          font-variant-numeric: tabular-nums; }
.stat span { font: 500 var(--fs-small)/1 var(--font-ui);
             letter-spacing: var(--tr-small); text-transform: uppercase;
             color: var(--fg-muted); }
.stat.flag b { color: var(--attention); }

/* --------------------------------------------------------------------------
   SECTION / CARD
   -------------------------------------------------------------------------- */
.section {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  margin: 0 0 var(--space-6);
}
.stack-col > .section, .split > * > .section:last-child { margin-bottom: 0; }

.section.quiet { background: transparent; border-style: dashed; }
.section.flag  { border-color: var(--attention); }
.section.lift  { box-shadow: var(--shadow-2); }

.section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--space-4); flex-wrap: wrap;
  margin-bottom: var(--space-4);
}
.section-head h2 { margin: 0; }

/* Section titles are eyebrows, not headlines — the content is the headline. */
h2 {
  margin: 0 0 var(--space-4);
  font: 500 var(--fs-small)/var(--lh-small) var(--font-ui);
  letter-spacing: var(--tr-small); text-transform: uppercase;
  color: var(--fg-muted);
}
h2 .sub, .section-head .sub {
  font-weight: 400; text-transform: none; letter-spacing: 0;
  color: var(--fg-subtle);
}
h3 { margin: 0 0 var(--space-2);
     font: 500 var(--fs-h3)/var(--lh-h3) var(--font-display);
     letter-spacing: var(--tr-h3); }

.hint { font: 400 var(--fs-caption)/var(--lh-caption) var(--font-ui);
        color: var(--fg-subtle); margin: 0 0 var(--space-3); max-width: 62ch; }
.meta { font: 400 var(--fs-caption)/var(--lh-caption) var(--font-ui);
        color: var(--fg-muted); }
.empty { color: var(--fg-subtle); font: 400 var(--fs-body)/1.5 var(--font-text);
         font-style: italic; }
.warn { color: var(--attention); font-weight: 600; }

/* --------------------------------------------------------------------------
   LISTS
   -------------------------------------------------------------------------- */
ul.list, ul.timeline { list-style: none; margin: 0; padding: 0; }

ul.list > li {
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--border);
  display: flex; align-items: baseline; gap: var(--space-2); flex-wrap: wrap;
}
ul.list > li:first-child { padding-top: 0; }
ul.list > li:last-child { border-bottom: 0; padding-bottom: 0; }
ul.list > li.empty { display: block; }

/* A list that is the last thing before a form needs a rule to sit against. */
ul.list + form.stack,
ul.list + details,
.list-then-form { margin-top: var(--space-5); padding-top: var(--space-5);
                  border-top: 1px solid var(--border); }

ul.timeline > li {
  padding: var(--space-4) 0;
  border-bottom: 1px solid var(--border);
}
ul.timeline > li:first-child { padding-top: 0; }
ul.timeline > li:last-child { border-bottom: 0; padding-bottom: 0; }
ul.timeline p {
  margin: var(--space-2) 0 0;
  font: 400 var(--fs-body)/1.6 var(--font-text);  /* prose gets the serif */
  white-space: pre-wrap;
  color: var(--fg);
}
.tl-head { display: flex; gap: var(--space-2); align-items: baseline; flex-wrap: wrap; }
.tl-head b { font: 500 var(--fs-body)/1.3 var(--font-ui); }

/* Row that pushes its trailing controls to the far edge. */
.row-spread { display: flex; align-items: baseline; gap: var(--space-2);
              flex-wrap: wrap; width: 100%; }
.spacer { flex: 1 1 auto; }

.date {
  font-variant-numeric: tabular-nums;
  font: 500 var(--fs-caption)/1.45 var(--font-ui);
  color: var(--fg-muted);
  min-width: 84px; flex: 0 0 auto;
}
.date.warn { color: var(--attention); }

.pin { color: var(--accent); }

/* --------------------------------------------------------------------------
   PILLS
   -------------------------------------------------------------------------- */
.pill {
  display: inline-flex; align-items: center; gap: var(--space-1);
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 2px var(--space-3);
  font: 500 var(--fs-caption)/1.5 var(--font-ui);
  color: var(--fg-muted);
  text-decoration: none;
  white-space: nowrap;
}
a.pill { transition: border-color var(--dur-quick) var(--ease-out); }
a.pill:hover { border-color: var(--border-strong); color: var(--fg);
               text-decoration: none; }
.pill.on, .pill.given {
  background: var(--accent); border-color: var(--accent); color: var(--fg-on-accent);
}
a.pill.on:hover { color: var(--fg-on-accent); }
.pill.accent { background: var(--accent-wash); border-color: transparent;
               color: var(--accent); }
.pill.flag   { background: var(--attention-wash); border-color: transparent;
               color: var(--attention); }
.pill.quiet  { opacity: .6; }
.pill.clear  { border-style: dashed; }
.pill form.inline { display: inline-flex; }

.tags, .modes { display: flex; gap: var(--space-2); flex-wrap: wrap; }

/* --------------------------------------------------------------------------
   TABLE
   -------------------------------------------------------------------------- */
.table-wrap {
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  overflow: hidden; background: var(--bg-elev);
}
table.grid { width: 100%; border-collapse: collapse; }
.grid th {
  text-align: left; background: var(--bg-sunken);
  font: 500 var(--fs-small)/1.4 var(--font-ui);
  letter-spacing: var(--tr-small); text-transform: uppercase;
  color: var(--fg-muted);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.grid td { padding: var(--space-3) var(--space-4);
           border-bottom: 1px solid var(--border); vertical-align: top; }
.grid tbody tr:last-child td { border-bottom: 0; }
.grid tbody tr { transition: background var(--dur-quick) var(--ease-out); }
.grid tbody tr:hover { background: var(--ink-06); }
@media (prefers-color-scheme: dark) {
  .grid tbody tr:hover { background: rgb(255 250 248 / .04); }
}
.grid td .pill { margin-right: var(--space-1); }
.grid a { font-weight: 500; }

@media (max-width: 720px) {
  /* Cadence is the least useful column on a phone — drop it before squeezing
     names into two lines. */
  .grid th:nth-child(3), .grid td:nth-child(3) { display: none; }
}
@media (max-width: 600px) {
  /* Let the table scroll rather than crush the remaining columns. */
  .table-wrap { overflow-x: auto; }
  .grid { min-width: 420px; }
  .grid th, .grid td { padding: var(--space-3); }
}

/* --------------------------------------------------------------------------
   FORMS
   -------------------------------------------------------------------------- */
input, select, textarea, button { font: inherit; color: inherit; }

input, select, textarea {
  background: var(--bg-sunken);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3);
  width: 100%;
  font: 400 var(--fs-body)/1.4 var(--font-ui);
  transition: border-color var(--dur-quick) var(--ease-out);
}
input::placeholder, textarea::placeholder { color: var(--fg-subtle); }
input:hover, select:hover, textarea:hover { border-color: var(--fg-subtle); }
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--accent); box-shadow: var(--shadow-focus);
}
textarea { resize: vertical; font-family: var(--font-text); line-height: 1.6; }
select[multiple] { padding: var(--space-1); }

label {
  display: block;
  font: 500 var(--fs-caption)/1.4 var(--font-ui);
  color: var(--fg-muted);
  margin-bottom: var(--space-3);
}
label input, label select, label textarea { margin-top: var(--space-1); }
/* A hint inside a label sits on its own line. Inline, it wraps mid-phrase in
   narrow grid cells — "blank = use / tags" — which reads as broken. */
label .hint { display: block; margin: 2px 0 0; font-weight: 400; }

label.check {
  display: flex; align-items: center; gap: var(--space-2); margin: 0;
  color: var(--fg); font-weight: 400;
}
label.check input { width: auto; margin: 0; accent-color: var(--accent); }

form.stack { display: flex; flex-direction: column; gap: var(--space-3);
             margin-top: var(--space-4); align-items: stretch; }
form.stack > button { align-self: flex-start; }
form.inline { display: inline-flex; gap: var(--space-2); align-items: center;
              margin: 0; }
form.inline input { width: auto; }

.two   { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }
.three { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-3); }
@media (max-width: 520px) { .three { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.filters { display: flex; gap: var(--space-4); align-items: center;
           flex-wrap: wrap; margin-bottom: var(--space-5); }
.filters input[type=search] { max-width: 300px; }

form.ruleform { display: flex; gap: var(--space-4); align-items: flex-end;
                flex-wrap: wrap; margin: 0; width: 100%; }
form.ruleform label { margin: 0; }
form.ruleform input { width: auto; }

/* Fixed widths for the two numeric fields in a lead-time rule. A time input
   has to fit "08:00 AM" plus the browser's own clock affordance. */
.w-days { width: 5.5em; }
.w-time { width: 10em; }
form.envelope { display: flex; gap: var(--space-2); align-items: center; }
form.envelope input { min-width: 220px; }

/* --------------------------------------------------------------------------
   BUTTONS
   Brand rule: no hue shift on hover — elevate instead. Press sinks 1px.
   -------------------------------------------------------------------------- */
.btn, button {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--space-2);
  background: var(--accent); color: var(--fg-on-accent);
  border: 1px solid var(--accent);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-4);
  font: 500 var(--fs-body)/1.3 var(--font-ui);
  cursor: pointer; text-decoration: none; white-space: nowrap;
  transition: box-shadow var(--dur-base) var(--ease-out),
              transform var(--dur-quick) var(--ease-out);
}
.btn:hover, button:hover { box-shadow: var(--shadow-2); text-decoration: none;
                           color: var(--fg-on-accent); }
.btn:active, button:active { transform: translateY(1px); box-shadow: var(--shadow-1); }

.btn.ghost, button.ghost {
  background: transparent; color: var(--fg); border-color: var(--border-strong);
}
.btn.ghost:hover, button.ghost:hover { color: var(--fg); border-color: var(--fg-subtle); }

/* Inline text actions inside dense rows — done, pin, remove, ×. */
button.link {
  background: none; border: 0; color: var(--fg-muted);
  padding: 0 var(--space-1); font: 400 var(--fs-caption)/1.4 var(--font-ui);
  text-decoration: underline; text-underline-offset: 2px;
  box-shadow: none;
}
button.link:hover { color: var(--fg); box-shadow: none;
                    text-decoration-thickness: 2px; }
button.link:active { transform: none; }
button.link.danger:hover { color: var(--attention); }

/* --------------------------------------------------------------------------
   DISCLOSURE
   The list stays scannable; the editor is one click away.
   -------------------------------------------------------------------------- */
details { margin: 0; width: 100%; }
details > summary {
  cursor: pointer; list-style: none;
  padding: var(--space-1) 0;
  display: flex; align-items: baseline; gap: var(--space-2); flex-wrap: wrap;
  border-radius: var(--radius-sm);
}
details > summary::-webkit-details-marker { display: none; }
details > summary::before {
  content: "›"; color: var(--fg-subtle); flex: 0 0 auto;
  font-size: 15px; line-height: 1;
  transition: transform var(--dur-quick) var(--ease-out);
  transform-origin: 50% 55%;
}
details[open] > summary::before { transform: rotate(90deg); }
details > summary:hover { color: var(--accent); }
details[open] > summary { margin-bottom: var(--space-3); }
details form.stack, details > p {
  margin-left: var(--space-3);
  padding-left: var(--space-4);
  border-left: 2px solid var(--border);
}
details form.stack { margin-bottom: var(--space-3); }

/* --------------------------------------------------------------------------
   PERSON HEADER
   -------------------------------------------------------------------------- */
.person-head {
  display: flex; gap: var(--space-5); align-items: flex-start;
  flex-wrap: wrap; margin-bottom: var(--space-6);
}
.avatar {
  flex: 0 0 auto;
  width: 56px; height: 56px;
  display: grid; place-items: center;
  background: var(--accent-wash);
  color: var(--accent);
  border-radius: var(--radius-lg);
  font: 700 20px/1 var(--font-display); letter-spacing: -0.02em;
  text-transform: uppercase;
}
.person-head .who { flex: 1 1 260px; min-width: 0; }
.person-head h1 { margin: 0 0 var(--space-2);
                  font: 700 var(--fs-h1)/var(--lh-h1) var(--font-display);
                  letter-spacing: var(--tr-h1); }
.person-head .facts { display: flex; gap: var(--space-2); flex-wrap: wrap;
                      align-items: center; }

/* --------------------------------------------------------------------------
   CALLOUT
   -------------------------------------------------------------------------- */
.callout {
  border-left: 2px solid var(--attention);
  background: var(--attention-wash);
  border-radius: var(--radius-sm);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-4);
}
.callout .hint { color: var(--fg-muted); margin: 0; }

/* --------------------------------------------------------------------------
   MOTION PREFERENCES
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
}

/* --------------------------------------------------------------------------
   PRINT — the card list is the page people actually print.
   -------------------------------------------------------------------------- */
@media print {
  .app-header, form, button, .btn, .hint { display: none !important; }
  body::before { display: none; }
  body { background: #fff; color: #000; }
  .section { border-color: #ccc; break-inside: avoid; }
}

/* --------------------------------------------------------------------------
   SPACING UTILITIES
   A deliberately tiny set — enough to keep inline style= out of the
   templates, not enough to become a utility framework.
   -------------------------------------------------------------------------- */
.mt-3 { margin-top: var(--space-3); }
.mt-4 { margin-top: var(--space-4); }

/* Trailing actions on a dense row travel together. Left as separate flex
   items they wrap independently, stranding "Delete" on a line of its own. */
.row-actions { display: inline-flex; align-items: baseline; gap: var(--space-2);
               flex: 0 0 auto; margin-left: auto; }

/* A postal address, shown as it should be written on the envelope. Monospaced
   so the line breaks you see are the line breaks you get. */
pre.envelope-block {
  background: var(--bg-sunken); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: var(--space-3) var(--space-4);
  margin: 0; font: var(--fs-small)/var(--lh-small) var(--font-mono);
  white-space: pre-wrap;
}

/* The nudge-stalled banner. Uses .callout's attention treatment; it only ever
   appears when the scheduler has actually stopped, so it should read as a
   problem rather than as decoration. */
.callout p { margin: 0 0 var(--space-2); }
.callout p:last-child { margin-bottom: 0; }
.callout code {
  font: var(--fs-small)/var(--lh-small) var(--font-mono);
  background: var(--bg-sunken); border-radius: var(--radius-xs);
  padding: 0 var(--space-1);
}

/* Stat tiles are links. Every number on the dashboard leads somewhere — one
   you cannot act on is decoration, which is what a lifetime total was. */
a.stat { text-decoration: none; color: inherit; border-radius: var(--radius-sm); }
a.stat:hover b { color: var(--accent); }
a.stat:hover span { color: var(--fg); }
a.stat.flag:hover b { color: var(--attention); }
a.stat:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }

/* A relationship written out in full, both directions. The form says this back
   before you save, because "wife / husband" on its own never says who is who. */
.sentence {
  margin: var(--space-2) 0 0;
  font: var(--fs-small)/var(--lh-body) var(--font-text);
  color: var(--fg-muted);
}
.sentence[hidden] { display: none; }
#relform .sentence { color: var(--fg); }

/* Tag picker. A text input backed by a datalist, so one field both offers the
   existing tags and accepts a new one. The chevron is drawn on because a
   datalist input has no affordance of its own — without it nobody discovers
   there is a list behind it. */
form.tagform { display: flex; gap: var(--space-3); align-items: flex-end;
               flex-wrap: wrap; margin-top: var(--space-4); }
form.tagform label { margin: 0; font-size: var(--fs-caption); }
form.tagform input {
  width: auto; min-width: 18rem; padding-right: var(--space-8);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%236b6862' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-3) center;
  background-size: 12px 8px;
}
form.tagform input::-webkit-calendar-picker-indicator { opacity: 0; cursor: pointer; }
