/* Bob's desk and the sign-in page: the client-facing pages on app.deepbob.com. Built from the boards in
   experiments/portal/ (docs/PORTAL.md, step 4) on the brand's tokens (web/css/tokens.css). Served by Caddy at /static/. */
@font-face { font-family: "Funnel Display"; src: url("fonts/FunnelDisplay-Light.woff2") format("woff2"); font-weight: 300; font-display: swap; }
@font-face { font-family: "Funnel Display"; src: url("fonts/FunnelDisplay-Regular.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Google Sans"; src: url("fonts/GoogleSans-Regular.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Funnel Display"; src: url("fonts/FunnelDisplay-Medium.woff2") format("woff2"); font-weight: 500; font-display: swap; }
/* the brand's tokens (web/css/tokens.css) */
:root {
  color-scheme: light;
  --ink: oklch(16% 0.035 250);
  --n-0: oklch(97.5% 0.003 70);
  --n-1: oklch(93.6% 0.004 70);
  --n-4: oklch(70% 0.006 70);
  --n-5: oklch(60% 0.007 70);
  --n-6: oklch(49% 0.008 70);
  --n-7: oklch(37.4% 0.008 70);
  --white: oklch(100% 0 0);
  --red: oklch(59% 0.23 28);   /* Bob red: once, where a person is needed */
  --coral: oklch(75% 0.12 38);
  --coral-ink: oklch(20% 0.04 38);
  --shallow: oklch(86% 0.06 215);
  --shell: oklch(90% 0.045 15);
  --line: color-mix(in oklch, var(--ink) 13%, transparent);
  --quiet: var(--n-6);
  --display: "Funnel Display", "Google Sans", system-ui, sans-serif;
  --text: "Google Sans", system-ui, sans-serif;
  --ease: cubic-bezier(0.2, 0, 0, 1);
}
* { box-sizing: border-box; }
html, body { margin: 0; }
body { font: 16px/1.4 var(--text); letter-spacing: -0.006em; color: var(--ink); background: var(--n-0); -webkit-font-smoothing: antialiased; }
p, h1, h2, ol, ul, dl, dd, figure { margin: 0; padding: 0; }
ol, ul { list-style: none; }
img { display: block; max-width: 100%; }
[hidden] { display: none !important; }
.display { font-family: var(--display); font-weight: 300; letter-spacing: -0.02em; line-height: 1.02; text-wrap: balance; }
.label { font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--quiet); }
.mark { font-family: var(--display); font-weight: 400; letter-spacing: -0.01em; font-size: 20px; color: var(--ink); text-decoration: none; }
.num { font-variant-numeric: tabular-nums; }
.quiet { color: var(--quiet); }
.dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--red); vertical-align: middle; }
.dek { font-size: 19px; line-height: 1.4; margin-top: 16px; max-width: 36ch; }
.msg { margin-top: 14px; font-size: 15px; min-height: 1.4em; }
.msg.is-error { color: var(--coral-ink); }
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  text-decoration: none;
  font: inherit;
  font-size: 16px;
  border-radius: 999px;
  padding: 14px 22px;
  border: 1px solid var(--ink);
  background: none;
  color: var(--ink);
  cursor: pointer;
  text-align: center;
  transition: background 200ms var(--ease), color 200ms var(--ease), transform 150ms var(--ease);
}
.btn:active { transform: scale(.98); }
.btn--do { background: var(--ink); color: var(--n-0); }
.btn:focus-visible, input:focus-visible, a:focus-visible { outline: 2px solid var(--red); outline-offset: 3px; }
.btn[disabled] { opacity: .5; cursor: default; }
/* ---------- controls and messages: buttons, waiting, errors and receipts, shared by every page ---------- */
button[aria-busy="true"] { opacity: .75; cursor: progress; }
.btn:disabled { cursor: not-allowed; }
.btn--do[aria-busy="true"] { opacity: .88; } /* waiting, not disabled */
.btn[aria-busy="true"] { opacity: 1; white-space: nowrap; }   /* waiting: a ring that turns, the button's size kept; the words on a line beneath (busy() in the desk script) */
.btn.is-done { background: var(--n-0); color: var(--ink); }
.btn--text {
  border: none;
  background: none;
  padding: 8px 2px;
  border-radius: 0;
  font-size: 14px;
  color: var(--n-7);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--n-4);
  min-height: 44px;
}
.btn--text:hover { color: var(--ink); text-decoration-color: var(--ink); }
.h-next { display: block; }
.msg-more { display: block; margin-top: 6px; }
input.code { text-overflow: ellipsis; }
.btn[aria-busy="true"][disabled] { opacity: 1; border-color: var(--ink); }
.view .only, .dek { text-wrap: pretty; }
bdi.keep { white-space: nowrap; }
.btn[aria-busy="true"]::before {
  content: "";
  flex: none;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid currentColor;
  border-right-color: transparent;
  animation: spin 800ms linear infinite;
}
.answers .btn { padding-inline: 28px; } /* room kept for the ring, so waiting changes nothing around the button */
.btn.is-spin { position: relative; padding-left: 38px; padding-right: 18px; } /* the same width: the word moves over for the ring */
.btn.is-spin::before { position: absolute; left: 16px; top: 0; bottom: 0; margin: auto 0; }
@keyframes spin { to { transform: rotate(1turn); } }
.busy-note { margin-top: 10px; font-size: 15px; color: var(--ink); }
/* a failed decision says so as clearly as the door does */
.view .msg.is-error:not(:empty) { border-left: 2px solid var(--red); padding-left: 12px; font-size: 16px; max-width: 65ch; color: var(--ink); }
@media (prefers-reduced-motion: reduce) {
  .btn[aria-busy="true"]::before { animation: none; }
}
/* ---------- the frame: rail on a wide screen, a bar on a phone ---------- */
.app { min-height: 100vh; display: grid; grid-template-columns: 248px minmax(0, 1fr); }
.rail { background: var(--n-1); padding: 32px 28px; display: flex; flex-direction: column; gap: 44px; }
.rail nav ul { display: grid; gap: 2px; }
.rail nav a { display: flex; justify-content: space-between; align-items: center; padding: 9px 0; color: var(--n-7); text-decoration: none; font-size: 15px; }
.rail nav a[aria-current] { color: var(--ink); }
.rail__who { margin-top: auto; font-size: 13px; color: var(--quiet); line-height: 1.5; }
.rail__who .who-out { display: inline-flex; align-items: center; min-height: 32px; margin-top: 10px; font-size: 14px; }   /* Logga ut: back to the door, so another passkey can sign in */
.menu-btn { display: none; }
.work { padding: 48px 72px 40px; min-width: 0; }
.view { max-width: 1040px; animation: rise 300ms var(--ease) both; }
@keyframes rise { from { opacity: 0; transform: translateY(8px); } }
@media (min-width: 900px) {
  /* where you are, said by weight */
  .rail nav a[aria-current] { font-weight: 600; }
}
/* ---------- signed out ---------- */
.door { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); min-height: 100vh; }
.door__text { padding: 40px 72px; display: flex; flex-direction: column; }
.door__text .body { margin-block: auto; padding-block: 40px; }
.door h1 { font-size: 72px; margin-top: 18px; }
.door .btn { margin-top: 32px; min-width: 260px; }
.door__pic { position: relative; }
.door__pic img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* a failure does not move the page; the computer hint is readable */
.door .msg { min-height: 4.2em; max-width: 46ch; }
.door .msg.is-error:not(:empty) { border-left: 3px solid var(--red); padding-left: 12px; } /* an error is not body text */
.door .body > :has(+ .btn), .door .body > :has(+ #msg + .btn) { margin-bottom: 8px; }
.door .body > .msg:not(:empty) + .btn { margin-top: 16px; }
.door .body > .msg:empty:has(+ .btn) { min-height: 0; margin: 0; } /* above a button an empty message takes no room; below one it keeps the page still */
/* connecting an app: the verdict first */
.door .msg b { font-weight: 600; }
.door .msg-more { margin-top: 12px; }
.door #providers:empty { display: none; } /* no sign-in providers: no gap where they would be */
/* the door: the error under the button it answers; empty, it takes no room */
.door .btn + .msg:empty { min-height: 0; margin: 0; }
.door .btn + .msg:not(:empty) { margin-top: 14px; }
.door .btn + .msg + .only { margin-top: 14px; }
/* the invitation: the instructions beside the code outrank the background */
.door--enroll .dek { font-size: 18px; line-height: 1.45; }
.door .only { margin-top: 14px; color: var(--ink); font-size: 15px; max-width: 52ch; }
@media (max-width: 899px) {
  /* the doors: the picture introduces, the task arrives on the first screen */
  .door .door__pic { height: 220px; }
  .door--enroll .door__pic { height: 260px; }
  .door__pic img { object-position: 50% 53%; } /* all of Bob and the key, not the counter */
  .door .only { font-size: 16px; line-height: 1.45; }
  .door--enroll .dek { line-height: 26px; }
  /* connecting an app, after a failure: the error and its retry come straight under the headline, the explanation after */
  .door--task .body:has(> #msg.is-error:not(:empty)) > * { order: 3; }
  .door--task .body:has(> #msg.is-error:not(:empty)) > .label, .door--task .body:has(> #msg.is-error:not(:empty)) > h1 { order: 0; }
  .door--task .body:has(> #msg.is-error:not(:empty)) > #msg { order: 1; margin-top: 18px; }
  .door--task .body:has(> #msg.is-error:not(:empty)) > #go { order: 2; margin-top: 14px; }
  .door--task .body:has(> #msg.is-error:not(:empty)) > .dek { margin-top: 28px; }
}
/* ---------- one decision ---------- */
.ask h1 { font-size: 60px; margin-top: 16px; }
.change { margin-top: 32px; background: var(--white); border-radius: 4px; display: grid; grid-template-columns: 1fr 1fr; }
.change > div { padding: 20px 24px 22px; }
.change > div + div { border-left: 1px solid var(--line); }
.change .v { font-family: var(--display); font-weight: 300; font-size: 40px; line-height: 1.05; margin-top: 8px; overflow-wrap: anywhere; }
.change .is-new .v bdi { display: inline-block; padding-bottom: 6px; border-bottom: 4px solid var(--red); } /* the new value, marked: a bar, not a squiggle */
.claim { margin: 14px 0 0; padding: 14px 18px; border-left: 2px solid var(--ink); max-width: 640px; }
.claim p:last-child { margin-top: 6px; font-size: 16px; line-height: 1.42; color: var(--n-7); white-space: pre-line; } /* a note keeps its lines */
.only { margin-top: 26px; font-size: 15px; max-width: 640px; }
.only + .answers { margin-top: 12px; }
/* the fraud warning: Bob on the white ground, a red rule, like every other alert on the desk */ /* the warning's Bob is the brand's alert face, drawn: crisp on white, no picture ground to melt */
.warn {
  margin-top: 14px;
  border-radius: 4px;
  display: grid;
  overflow: hidden;
  max-width: 640px;
  align-items: center;
  background: var(--white);
  color: var(--ink);
  box-shadow: inset 3px 0 0 var(--red);
  grid-template-columns: 76px 1fr;
}
.warn img { align-self: center; object-fit: contain; width: 52px; height: auto; margin: 12px 0 12px 18px; }   /* the brand's drawn alert Bob (img/bob-alert.svg) */
.warn p { font-size: 15px; line-height: 1.4; padding: 12px 20px 12px 4px; }
.answers { display: flex; gap: 12px; margin-top: 28px; flex-wrap: wrap; align-items: center; }
.more { margin-top: 48px; }
.more li button { all: unset; cursor: pointer; display: flex; justify-content: space-between; gap: 16px; width: 100%; padding: 12px 0; border-top: 1px solid var(--line); font-size: 15px; }
.more li button:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
/* a decision says what each answer does, as two lines a person can compare */
.consequence { margin-top: 22px; max-width: 640px; display: grid; gap: 6px; font-size: 16px; }
.consequence div { display: grid; grid-template-columns: 92px minmax(0, 1fr); gap: 12px; }
.consequence dt { font-weight: 600; }
.consequence dd { margin: 0; }
.consequence + .only { margin-top: 12px; font-size: 14px; color: var(--n-7); }
@media (max-width: 899px) {
  /* the decision on a phone: the question outranks its facts */
  .change > div { padding: 14px 18px 16px; }
}
.change.is-receipt { max-width: 640px; margin-top: 10px; }
.change.is-receipt .v { font-size: 32px; }
/* ---------- nothing needs you ---------- */
.view.calm { max-width: none; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 48px; align-items: end; min-height: calc(100vh - 88px); }
.calm figure { align-self: stretch; margin: -48px -72px -40px 0; position: relative; } /* the picture runs to the edges, as on the board */
.calm h1 { font-size: 80px; margin-top: 18px; }
.dots { display: flex; flex-wrap: wrap; gap: 9px; margin-top: 14px; max-width: 400px; }
.dots i { width: 10px; height: 10px; border-radius: 50%; background: var(--ink); }
.dots i.is-person { background: none; box-shadow: inset 0 0 0 1.5px var(--ink); }
.today { margin-top: 44px; }
.today p:last-child { margin-top: 14px; font-size: 13px; color: var(--quiet); }
.calm figure img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* ---------- signed: the stamp ---------- */
.stamp {
  width: 132px;
  height: 132px;
  border-radius: 50%;
  border: 3px solid var(--red);
  color: var(--red);
  display: grid;
  place-content: center;
  text-align: center;
  transform: rotate(-9deg);
  box-shadow: inset 0 0 0 5px var(--n-0), inset 0 0 0 6px color-mix(in oklch, var(--red) 60%, transparent);
  animation: stamp 420ms cubic-bezier(.2, 1.6, .4, 1) both;
}
@keyframes stamp { from { transform: rotate(-9deg) scale(1.25); opacity: 0; } }
.stamp small { text-transform: uppercase; font-family: var(--display); font-weight: 500; font-size: 19px; letter-spacing: .04em; }
.stamp b { font-weight: 400; line-height: 1; font-family: var(--text); font-size: 14px; margin-top: 4px; }
.signed h1 { font-size: 48px; margin-top: 32px; }
.signed .note { margin-top: 22px; padding-top: 14px; border-top: 1px solid var(--line); font-size: 14px; max-width: 520px; }
.view.ask > *, .view.signed > * { max-width: 880px; }
/* a settled decision keeps its seal */
.stamp--settled { width: 108px; height: 108px; }
.stamp--settled small { font-size: 16px; }
@media (max-width: 899px) {
  .stamp--settled { width: 100px; height: 100px; }
  .stamp--settled small { font-size: 12px; letter-spacing: .02em; }
  .stamp--settled b { font-size: 12px; }
}
/* ---------- the record ---------- */
.record h1 { font-size: 48px; margin-top: 16px; }
.record ol { margin-top: 28px; }
.record li { display: grid; grid-template-columns: 110px 150px minmax(0, 1fr); gap: 16px; padding: 12px 0; border-top: 1px solid var(--line); font-size: 14px; }
.record li > span:first-child { color: var(--quiet); }
.record li.is-done > span:nth-child(3), .record li.is-asked > span:nth-child(3) { color: var(--ink); } /* the record: everyone's lines in the same ink; who it was is said by the name's weight */
.record li.is-person { border-radius: 4px; background: none; margin-inline: 0; padding-inline: 0; border-top-color: var(--line); } /* the record: who did it is the rule, said by the name's weight, not by a card that looks selected */
.record li.is-person > span:nth-child(2), .record li.is-person > span:nth-child(3) { color: var(--ink); }
/* the record, searched: one field, three rows of filters, the days as headings (2026-11-07) */
.rq { margin-top: 26px; display: grid; gap: 12px; }
.rq-search { display: grid; gap: 8px; margin-bottom: 6px; }
.rq-search input {
  font: inherit;
  padding: 14px 16px;
  border: 0;
  border-radius: 4px;
  background: var(--white);
  color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--line);
  min-width: 0;
  font-size: 16px;
}
.rq-search input:focus { outline: none; box-shadow: inset 0 0 0 1.5px var(--ink); }
.rq-search input::placeholder { color: var(--n-4); }
.rq-row { display: grid; grid-template-columns: 56px minmax(0, 1fr); gap: 12px; align-items: center; }
.rq-row .label { margin: 0; }
.rq-when { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
/* the filters are separate chips, not one long pill: they wrap to any width without becoming a blob */
.rq .seg { box-shadow: none; padding: 0; gap: 6px; }
.rq .seg button, .rq-dayin button { box-shadow: inset 0 0 0 1px var(--line); }
.rq .seg button.on, .rq-dayin button.on { box-shadow: none; }
.rq-dayin { position: relative; display: inline-flex; }
.rq-dayin button {
  all: unset;
  cursor: pointer;
  font-size: 12px;
  padding: 5px 10px;
  border-radius: 999px;
  color: var(--n-7);
  box-shadow: inset 0 0 0 1px var(--line);
  transition: background 200ms var(--ease), color 200ms var(--ease);
}
.rq-dayin button.on { background: var(--ink); color: var(--n-0); box-shadow: none; }
.rq-dayin button:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
.rq-dayin input { position: absolute; inset: 0; opacity: 0; pointer-events: none; width: 100%; border: 0; padding: 0; }
.rq-search input::-webkit-search-cancel-button { -webkit-appearance: none; }
.rq-rows { display: grid; gap: 12px; }
.rq-toggle { display: none; }
.rq-sum { margin-top: 30px; font-size: 14px; color: var(--n-7); }
.rq-sum .linkish { margin-left: 6px; }
.rq-printed { display: none; }
.record .rq-group ol { margin-top: 0; }
.rq-dayhead {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--n-0);
  margin: 26px 0 0;
  padding: 10px 0 8px;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink);
}
.rq-whobtn { all: unset; cursor: pointer; border-radius: 2px; }
.rq-whobtn:hover { text-decoration: underline; text-underline-offset: 3px; }
.rq-whobtn:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
.rq-list mark { background: color-mix(in oklch, var(--red) 16%, transparent); color: inherit; border-radius: 2px; padding: 0 1px; }
.rq-empty { margin-top: 18px; padding: 26px 0; border-top: 1px solid var(--line); display: grid; gap: 14px; justify-items: start; }
.rq-empty p { margin: 0; }
.record li.is-person > span:nth-child(2) { font-weight: 600; }
@media print {
  .rq-list { max-width: 170mm; }
}
@media screen and (min-width: 900px) {
  /* the record: evidence read at body size, actor next to the act, a line a person can follow */
  /* screen only: the phone has its own two columns, the print its own sizes */
  .record li { grid-template-columns: 64px 128px minmax(0, 1fr); font-size: 16px; line-height: 1.42; }
  .record li > span:nth-child(3) { max-width: 75ch; }
}
@media (max-width: 899px) {
  .rq-when .seg { display: contents; } /* När: the day picker wraps with the other days, one group */
  /* the record: search and Filtrera on one row; the count close to the first day; Vad's chips at their own width */
  .rq { grid-template-columns: minmax(0, 1fr) auto; column-gap: 8px; row-gap: 10px; align-items: end; }
  .rq-search { margin-bottom: 0; }
  .rq-sum { margin-top: 16px; }
  .rq-group:first-of-type .rq-dayhead { margin-top: 10px; }
}
/* ---------- sign-in code page ---------- */
.signin { max-width: 440px; margin: 0 auto; padding: 24px 22px 32px; min-height: 100vh; display: flex; flex-direction: column; }
.signin .bar { display: flex; justify-content: space-between; align-items: center; font-size: 14px; }
.signin h1 { font-size: 40px; margin-top: 14px; }
.signin form { display: flex; flex-direction: column; flex: 1; }
.code {
  margin-top: 26px;
  width: 100%;
  font: 300 30px/1 var(--display);
  letter-spacing: .12em;
  text-transform: uppercase;
  text-align: center;
  padding: 18px 12px;
  border-radius: 4px;
  border: 0;
  background: var(--white);
  color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--line);
}
.code:focus { box-shadow: inset 0 0 0 1.5px var(--ink); outline: none; }
.code::placeholder { color: var(--n-4); }
.back { margin-top: 18px; font-size: 14px; line-height: 1.45; color: var(--n-7); }
.back b { font-weight: 400; color: var(--ink); }
.boundary { margin-top: 22px; padding-top: 14px; border-top: 1px solid var(--line); font-size: 14px; line-height: 1.45; }
.signin .lead { margin-top: 18px; font-size: 16px; }
.signin form.go { flex: none; margin-top: 28px; }
.signin form.go .btn { margin-top: 0; }
.fallback { margin-top: auto; padding-top: 28px; font-size: 14px; }
.fallback summary { cursor: pointer; color: var(--n-7); }
.fallback form { flex: none; }
.fallback .code { margin-top: 14px; }
.fallback .btn { margin-top: 14px; }
.signin .btn { margin-top: auto; width: 100%; }
.signin .msg { margin-bottom: 8px; }
/* ---------- phone ---------- */
@media (max-width: 899px) {
  .app { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto 1fr; } /* minmax: the tabs' min-content never widens the page */
  .rail { min-width: 0; padding: 12px 22px; gap: 0; background: var(--n-0); border-bottom: 1px solid var(--line); }
  .rail__bar { display: flex; justify-content: space-between; align-items: center; min-height: 44px; }
  .menu-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font: inherit;
    font-size: 15px;
    color: var(--ink);
    background: none;
    border: 1px solid var(--ink);
    border-radius: 999px;
    padding: 9px 18px;
    cursor: pointer;
    min-height: 44px;
  }
  .menu-btn:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
  .rail nav, .rail__who { display: none; } /* the pages sit behind Meny on a phone, never in a row you have to swipe */
  .rail.is-open nav { display: block; margin-top: 10px; }
  .rail nav ul { gap: 0; }
  .rail nav li + li { border-top: 1px solid var(--line); }
  .rail nav a { font-family: var(--display); font-weight: 300; font-size: 28px; letter-spacing: -0.01em; padding: 13px 0; color: var(--n-7); justify-content: flex-start; gap: 12px; min-height: 56px; }
  .rail nav a::before { content: ""; flex: none; width: 7px; height: 7px; border-radius: 50%; }
  .rail nav a[aria-current] { color: var(--ink); }
  .rail nav a[aria-current]::before { background: var(--ink); } /* where you are */
  .rail nav a .dot { margin-left: 4px; }
  .rail.is-open .rail__who { display: block; padding: 16px 0 8px; border-top: 1px solid var(--line); }
  .rail__who .who-out { min-height: 44px; font-size: 16px; }
  .work { padding: 26px 22px 28px; }
  .door { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  .door__pic { order: -1; height: 38vh; }
  .door__text { padding: 22px; }
  .door__text .body { padding-block: 20px 0; margin-block: 0; display: flex; flex-direction: column; flex: none; }
  .door h1 { font-size: 40px; }
  .door .btn { width: 100%; margin-top: 32px; }
  .ask h1 { font-size: 38px; }
  .change { grid-template-columns: 1fr; }
  .change > div + div { border-left: 0; border-top: 1px solid var(--line); }
  .change .v { font-size: 27px; }
  .answers { flex-direction: column; }
  .answers .btn { width: 100%; }
  .view.calm { grid-template-columns: 1fr; gap: 28px; min-height: 0; } /* .view.calm, or the desktop rule's two classes win on a phone */
  .calm h1 { font-size: 60px; }
  .calm figure { order: -1; margin: -26px -22px 0; }
  .held ~ .view.calm figure { margin-top: 0; } /* a banner above: the picture starts below it, not under it */
  .calm figure img { position: static; aspect-ratio: 4 / 3; height: auto; }
  .signed h1, .record h1 { font-size: 36px; }
  .record li { row-gap: 2px; font-size: 16px; grid-template-columns: 48px minmax(0, 1fr); gap: 2px 12px; }
  .record li > span:nth-child(2) { color: var(--quiet); }
  .record li > span:nth-child(3) { grid-column: 2; }
  .rq-row { grid-template-columns: 1fr; gap: 6px; }
  .rq-toggle {
    all: unset;
    display: inline-flex;
    justify-self: start;
    cursor: pointer;
    font-size: 14px;
    border-radius: 999px;
    box-shadow: inset 0 0 0 1px var(--line);
    color: var(--ink);
    min-height: 50px;
    padding: 0 18px;
    box-sizing: border-box;
    align-items: center;
    justify-content: center;
  }
  .rq-toggle.on { background: var(--ink); color: var(--n-0); box-shadow: none; }
  .rq-toggle:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
  .rq:not(.open) .rq-rows { display: none; }
  .rq-rows { padding-top: 6px; grid-column: 1 / -1; gap: 10px; }
  .rq-search input { font-size: 16px; }
  .rq-dayin button { padding: 12px 16px; font-size: 15px; }
}
@media (prefers-reduced-motion: reduce) {
  .view, .stamp { animation: none; }
}
/* ---------- the week: the Friday report on the desk, printable to A4 (from experiments/portal/report-a4.html) ---------- */
.week h1 { font-size: 64px; margin-top: 18px; max-width: 18ch; }
.week .dek { max-width: 46ch; }
.days { --bars: 200px; position: relative; margin-top: 52px; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); column-gap: 24px; }
.goal { position: absolute; left: 0; right: 0; top: 0; height: var(--bars); pointer-events: none; }
.goal i { position: absolute; left: 0; right: 0; bottom: var(--g); border-top: 1.5px dashed color-mix(in oklch, var(--ink) 55%, transparent); }
.goal p { position: absolute; right: 0; bottom: calc(var(--g) + 8px); font-size: 13px; color: var(--n-7); background: var(--n-0); padding-left: 8px; }
.day { display: grid; grid-template-rows: var(--bars) auto; min-width: 0; }
.day > i { align-self: end; width: 40px; background: var(--ink); border-radius: 20px 20px 0 0; }
.day.is-under > i { background: var(--coral); } /* red stays for a person needed */
.day.is-open > i { background: repeating-linear-gradient(135deg, transparent 0 8px, color-mix(in oklch, var(--ink) 18%, transparent) 8px 10px); box-shadow: inset 0 0 0 1.5px var(--ink); }
.day footer { border-top: 1px solid var(--ink); padding-top: 12px; display: grid; gap: 4px; align-content: start; }
.day footer b { font-weight: 400; font-size: 15px; text-transform: capitalize; }
.day footer span { font-family: var(--display); font-weight: 300; font-size: 30px; line-height: 1; }
.check { font-size: 12px; color: var(--quiet); display: flex; gap: 7px; align-items: baseline; }
.check::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--ink); flex: none; }
.check.is-open::before { background: none; box-shadow: inset 0 0 0 1.5px var(--ink); }
.week .key { display: none; gap: 16px; flex-wrap: wrap; margin-top: 14px; font-size: 12px; color: var(--quiet); }
.week .key .check { font-size: 12px; }
.week .mid { margin-top: 56px; display: grid; grid-template-columns: 5fr 7fr; gap: 40px; align-items: start; }
.week .mid figure img { width: 100%; aspect-ratio: 5 / 4; object-fit: cover; object-position: 50% 60%; border-radius: 4px; }
.week .mid figcaption { margin-top: 10px; font-size: 13px; color: var(--quiet); }
.saw .label { margin-bottom: 12px; }
.saw li { display: grid; grid-template-columns: 44px 1fr; padding: 14px 0 16px; border-top: 1px solid var(--line); font-size: 19px; line-height: 1.35; }
.saw li b { font-weight: 400; font-size: 13px; color: var(--quiet); padding-top: 5px; }
.week .band { margin-top: 56px; background: var(--shallow); border-radius: 4px; padding: 32px 36px 28px; display: grid; grid-template-columns: 1fr 1fr; gap: 24px 40px; }
.week .band .big-line { margin-top: 10px; font-size: 21px; line-height: 1.38; }
.week .band .n { font-family: var(--display); font-weight: 300; font-size: 56px; line-height: 1; margin-top: 10px; }
.week .band p:last-child:not(.foot) { margin-top: 8px; }
.week .band .foot { grid-column: 1 / -1; color: color-mix(in oklch, var(--ink) 72%, transparent); font-size: 15px; }
@media (max-width: 899px) {
  .week h1 { font-size: 38px; }
  .days { --bars: 110px; column-gap: 10px; margin-top: 32px; }
  .day > i { width: 22px; }
  .day footer span { font-size: 17px; }
  .day footer b { font-size: 12px; }
  .check { font-size: 0; } /* on a phone the dot says it; the key under the chart says what the dots mean */
  .week .key { display: flex; }
  .goal p { font-size: 11px; }
  .week .mid { grid-template-columns: 1fr; gap: 24px; margin-top: 36px; }
  .saw li { font-size: 16px; grid-template-columns: 32px 1fr; }
  .week .band { grid-template-columns: 1fr; padding: 24px 22px; margin-inline: -22px; border-radius: 0; }
}
@media print {
  @page { size: A4; margin: 14mm; }
  .rail, .no-print { display: none !important; }
  .app { display: block; }
  .work { padding: 0; }
  .view { animation: none; max-width: none; }
  body { background: #fff; }
  .goal p { background: #fff; font-size: 9px; }
  /* A4 is narrower than the phone breakpoint: undo the phone layout and size everything to one sheet */
  .week h1 { font-size: 36px; margin-top: 10px; }
  .week .dek { font-size: 14px; margin-top: 10px; }
  .days { --bars: 120px; column-gap: 16px; margin-top: 26px; }
  .day > i { width: 26px; }
  .day footer span { font-size: 20px; }
  .day footer b { font-size: 11px; }
  .check { font-size: 9px; }
  .week .key { display: none; }
  .week .mid { grid-template-columns: 5fr 7fr; gap: 22px; margin-top: 26px; }
  .week .mid figure img { aspect-ratio: 4 / 3; }
  .saw li { font-size: 12px; grid-template-columns: 26px 1fr; padding: 8px 0 9px; }
  .week .band { margin: 24px 0 0; border-radius: 4px; padding: 18px 20px; gap: 12px 24px; background: none; border: 1px solid var(--line); grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr); }
  .week .band .big-line { font-size: 13px; }
  .week .band .n { font-size: 34px; }
  .week .band .foot { font-size: 9px; }
  .label { font-size: 9px; }
  .week, .week .mid, .week .band { break-inside: avoid; }
  * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .record h1 { font-size: 30px; }
  .rq-sum { margin-top: 10px; font-size: 12px; color: var(--ink); }
  .rq-printed { display: block; color: var(--n-7); margin-top: 4px; font-size: 12px; }
  .rq-dayhead { position: static; background: none; font-size: 10px; margin-top: 14px; padding: 4px 0; }
  .record li { break-inside: avoid; padding: 7px 0; grid-template-columns: 52px 120px minmax(0, 1fr); font-size: 13px; line-height: 1.45; }
  .rq-list mark { background: none; font-weight: 600; }
  .record li > span:nth-child(3) { grid-column: auto; }
}
/* the week: each decision its own line, then what Bob did on his own */
.dec-list { margin-top: 12px; display: grid; gap: 10px; font-size: 18px; line-height: 1.35; }
.dec-list small { display: block; font-size: 14px; color: var(--n-7); margin-top: 2px; }
.week .band .waiting { margin-top: 12px; font-size: 15px; }
.own { margin-top: 28px; background: var(--white); border-radius: 4px; padding: 22px 32px 18px; }
.own ol { margin-top: 8px; }
.own li { display: grid; grid-template-columns: 110px minmax(0, 1fr); gap: 16px; padding: 10px 0; border-top: 1px solid var(--line); font-size: 15px; }
.own .linkish { display: inline-block; margin-top: 10px; }
.dec-list .quiet { margin-right: 6px; font-size: 14px; color: color-mix(in oklch, var(--ink) 66%, transparent); }
.week .own li { max-width: none; }
/* the week: each decision a record, its date in a column; the lower lists at a reading measure; the number holds its side */
.dec-list li { display: grid; grid-template-columns: 84px minmax(0, 1fr); gap: 2px 14px; align-items: baseline; }
.dec-list li > .quiet { margin: 0; }
.own li > span:last-child { max-width: 75ch; }
@media (max-width: 899px) {
  .own { margin-inline: -22px; border-radius: 0; padding: 20px 22px; }
  .own li { grid-template-columns: 1fr; gap: 2px; }
  .dec-list li { grid-template-columns: 1fr; } /* the date a line above its decision */
}
@media print {
  .week .own li { padding-inline: 0; }
  .week .own { margin-top: 18px; }
  .dec-list li { grid-template-columns: 56px minmax(0, 1fr); }
}
@media screen and (min-width: 900px) {
  /* the week: the decisions get the room, the number the rest; a date is metadata */
  .week .band { grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr); }
  .week .band .n { font-size: 72px; }
}
/* ---------- what Bob may do: the client's rules (from experiments/portal/desk-rules.html) ---------- */
.rules h1 { font-size: 44px; margin-top: 12px; }
.meanings { display: flex; gap: 26px; margin-top: 16px; font-size: 14px; flex-wrap: wrap; }
.meanings dt { display: inline; }
.meanings dd { display: inline; margin: 0 0 0 6px; color: var(--quiet); }
.meanings dt::after { content: " ·"; color: var(--quiet); }
/* the rules read as a contract in sections (2026-11-07, after Bishop: the controls carry the page, not the headline):
   each zone a full-width band, its name on the left, its rules on the right, each answer beside its sentence */
.zones { margin-top: 28px; display: grid; gap: 14px; }
.zone { background: var(--white); border-radius: 4px; padding: 24px 32px 14px; display: grid; gap: 0 40px; grid-template-columns: 268px minmax(0, 1fr); }
.zone.is-read { order: 9; } /* what is always on goes last: the first thing on the page is a choice */
.zone--never { background: var(--shell); }
.zone h2 { font-family: var(--display); font-weight: 400; font-size: 26px; line-height: 1.12; letter-spacing: -0.015em; padding-top: 6px; }
.zone li { border-top: 1px solid var(--line); display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0 28px; align-items: center; padding: 16px 0 17px; } /* the rules: rows read at body size; the answers in one aligned column; the chosen answer weighs more */
.zone li:first-child { border-top: 0; }
.zone li > .row-label { line-height: 1.3; font-size: 18px; }
.zone li > em { grid-column: 1; margin-top: 3px; font-style: normal; max-width: 60ch; font-size: 14px; color: color-mix(in oklch, var(--ink) 78%, transparent); }
.zone li > .seg { grid-column: 2; grid-row: 1 / span 3; justify-self: end; }
.zone .seg button { font-size: 15px; padding: 10px 16px; } /* the rules: the answers are the page's controls, sized to be pressed */
.seg { display: inline-flex; gap: 2px; padding: 2px; border-radius: 999px; box-shadow: inset 0 0 0 1px var(--line); justify-self: start; flex-wrap: wrap; }
.seg button { all: unset; cursor: pointer; font-size: 12px; padding: 5px 10px; border-radius: 999px; color: var(--n-7); transition: background 200ms var(--ease), color 200ms var(--ease); }
.seg--big button { font-size: 14px; padding: 9px 16px; }
.seg button.on { background: var(--ink); color: var(--n-0); }
.seg button[disabled] { color: var(--n-4); cursor: not-allowed; text-decoration: line-through; text-decoration-color: var(--n-4); }
.seg button:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
.asym { margin-top: 22px; font-size: 15px; }
@media (max-width: 899px) {
  .rules h1 { font-size: 38px; }
  .zone { grid-template-columns: 1fr; padding: 20px 22px 10px; margin-inline: -22px; border-radius: 0; }
  .zone h2 { font-size: 24px; padding: 0 0 6px; }
  .zone li { grid-template-columns: 1fr; gap: 8px; row-gap: 4px; } /* a rule reads as one thing, then its answer */
  .zone li > .seg { grid-column: 1; justify-self: start; grid-row: 3; margin-top: 10px; }
  .rules .dek { display: none; }
  .seg button { padding: 8px 12px; font-size: 13px; } /* a thumb, not a cursor */
}
/* the rules' answer appears where the eye is, not 1 800 px down */
/* the rules: one family for every answer (in the page, white, an ink rule); the zone names room to breathe; the limit's controls drawn like the rest */
.rules > #msg:not(:empty) {
  bottom: 18px;
  z-index: 2;
  padding: 12px 20px;
  background: var(--ink);
  color: var(--n-0);
  box-shadow: 0 8px 24px rgb(0 0 0 / .18);
  font-size: 14px;
  border-radius: 18px;
  position: static;
  width: auto;
  max-width: none;
  margin: 16px 0 0;
}
.rules > #msg.is-error:not(:empty) { background: var(--coral-ink); }
/* one status object for an answer that lands: white, an ink rule, no shadow (the rules' toast, a removed device) */
.rules > #msg:not(:empty), .device-list + .msg:not(:empty) {
  background: var(--white);
  color: var(--ink);
  box-shadow: inset 3px 0 0 var(--ink), inset 0 0 0 1px var(--line);
  border-radius: 4px;
  padding: 12px 18px;
  font-size: 16px;
}
.rules > #msg.is-error:not(:empty), .device-list + .msg.is-error:not(:empty) { background: var(--white); box-shadow: inset 3px 0 0 var(--red), inset 0 0 0 1px var(--line); }
.rules #msg.is-here:not(:empty) {
  position: static;
  grid-column: 1 / -1;
  width: auto;
  max-width: none;
  margin: 12px 0 0;
  border-radius: 4px;
  background: var(--n-0);
  box-shadow: inset 3px 0 0 var(--ink);
  padding: 10px 16px;
  font-size: 16px;
  color: var(--ink);
}
.rules #msg.is-here.is-error:not(:empty) { box-shadow: inset 3px 0 0 var(--red); }
.zone .seg button.on { font-weight: 600; }
@media (max-width: 899px) {
  .zone li > .row-label { grid-row: 1; }
  .zone li > em { grid-row: 2; margin-top: 0; }
  .zone .seg button, .seg button { font-size: 15px; padding: 12px 16px; }
  /* the toast sits flush with the sections, not floating over them */
  .rules > #msg:not(:empty) { max-width: none; width: auto; margin-inline: -22px; border-radius: 0; bottom: 0; }
  .rules #msg.is-here:not(:empty) { margin-inline: 0; }
  .meanings { gap: 6px 18px; }
}
@media (min-width: 900px) {
  .zone li { grid-template-columns: minmax(0, 1fr) 312px; }
  .zone li > .seg { justify-self: start; }
}
/* ---------- the limit: what Bob may pay by himself (the site's contract, the board's Shallow panel) ---------- */
.limit { margin-top: 30px; background: var(--shallow); border-radius: 4px; padding: 22px 32px 20px; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px 40px; align-items: end; }
.limit p { font-size: 19px; }
.limit .amount { font-family: var(--display); font-weight: 300; font-size: 72px; line-height: 1; letter-spacing: -0.02em; margin-top: 4px; }
.limit .who { font-family: var(--display); font-weight: 300; font-size: 40px; line-height: 1.05; margin-top: 4px; } /* information, not a field */
.limit .slider { grid-column: 1 / -1; width: 100%; margin: 14px 0 4px; accent-color: var(--ink); -webkit-appearance: none; appearance: none; height: 28px; background: none; }
.limit-range { grid-column: 1 / -1; display: flex; justify-content: space-between; align-items: center; gap: 12px; font-size: 13px; margin-bottom: 6px; }
.limit-exact { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; }
.limit-exact input {
  font: inherit;
  font-size: 15px;
  width: 8.5em;
  border: 0;
  background: var(--white);
  color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--line);
  text-align: right;
  -moz-appearance: textfield;
  border-radius: 999px;
  padding: 7px 14px;
}
.limit-exact input:focus { outline: none; box-shadow: inset 0 0 0 1.5px var(--ink); }
.limit .limit-note { grid-column: 1 / -1; font-size: 13px; color: color-mix(in oklch, var(--ink) 72%, transparent); }
.stopped { margin-top: 14px; font-size: 16px; max-width: 640px; }
.stopped .label { display: block; margin-bottom: 4px; }
@media (max-width: 899px) {
  .limit { grid-template-columns: 1fr; padding: 20px 22px; margin-inline: -22px; border-radius: 0; }
  .limit .amount { font-size: 52px; }
  .limit .who { font-size: 30px; justify-self: start; }
}
.limit.is-pending .slider { opacity: .45; }   /* waiting for the passkey: the amount stays at full strength, the slider steps back */
.limit .pending-note { color: var(--ink); font-family: var(--display); font-weight: 400; font-size: 24px; letter-spacing: -0.01em; margin: 8px 0 4px; }
.limit + #msg.is-here:not(:empty) { margin: 10px 0 0; }
.limit .slider::-webkit-slider-runnable-track { height: 4px; border-radius: 2px; background: color-mix(in oklch, var(--ink) 22%, transparent); }
.limit .slider::-moz-range-track { height: 4px; border-radius: 2px; background: color-mix(in oklch, var(--ink) 22%, transparent); }
.limit .slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 22px;
  height: 22px;
  margin-top: -9px;
  border-radius: 50%;
  background: var(--ink);
  border: 3px solid var(--white);
  box-shadow: 0 0 0 1px var(--ink);
}
.limit .slider::-moz-range-thumb { width: 16px; height: 16px; border-radius: 50%; background: var(--ink); border: 3px solid var(--white); box-shadow: 0 0 0 1px var(--ink); }
.limit .slider:focus-visible { outline: 2px solid var(--red); outline-offset: 4px; }
.limit-exact input::-webkit-inner-spin-button, .limit-exact input::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.limit-exact input:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
/* ---------- connections: Bob reads the client's systems, one band each (the limit's band, on white: a fact, not a permission) ---------- */
.conns { margin-top: 30px; display: grid; gap: 12px; }
.conns:empty { display: none; }
.conn-head { margin-bottom: 2px; }
.conn { background: var(--white); border-radius: 4px; padding: 22px 32px 20px; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 6px 40px; align-items: end; }
.conn .label { display: flex; align-items: center; gap: 8px; }
.conn-dot { flex: none; width: 9px; height: 9px; border-radius: 50%; box-shadow: inset 0 0 0 1.5px var(--n-5); transition: background 200ms var(--ease); }
.conn.is-on .conn-dot { background: var(--ink); box-shadow: none; }
.conn-name { font-family: var(--display); font-weight: 300; line-height: 1.02; letter-spacing: -0.02em; margin-top: 6px; color: var(--n-5); font-size: 38px; }
.conn.is-on .conn-name { color: var(--ink); }
.conn-what { grid-column: 1; font-size: 16px; max-width: 60ch; margin-top: 10px; }
.conn-note { grid-column: 1 / -1; font-size: 13px; color: var(--quiet); }
.conn-act { justify-self: end; }
.conn-confirm { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: flex-end; }
.conn-confirm p { font-size: 15px; margin-right: 6px; }
.conn-confirm .btn { padding: 9px 16px; font-size: 14px; }
@media (max-width: 899px) {
  .conns { margin-inline: -22px; }
  .conn-head { padding-inline: 22px; }
  .conn { grid-template-columns: 1fr; padding: 20px 22px; border-radius: 0; }
  .conn-name { font-size: 34px; }
  .conn-act { justify-self: start; margin-top: 8px; }
  .conn-confirm { justify-content: flex-start; }
  .conn-confirm p { flex-basis: 100%; }
}
.conn .conn-act:has(.conn-confirm) { grid-column: 1 / -1; justify-self: stretch; }
.conn .conn-confirm { display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: center; }
.conn .conn-confirm p { flex: 1 1 100%; }
.conn-confirm + .busy-note { text-align: right; }
.conn:has(.conn-confirm) .conn-name { font-size: 32px; }
.conn .btn { padding: 11px 20px; font-size: 15px; }
@media (min-width: 900px) {
  .conn .conn-confirm { flex-wrap: nowrap; justify-content: flex-start; }
  .conn .conn-confirm p { flex: 1 1 auto; font-size: 17px; }
}
/* Kopplingar: how an AI app is connected (from the app, with this address), always the last card */
.conn-how .conn-name { font-size: 32px; }
.conn-url { grid-column: 1 / -1; display: flex; gap: 10px; align-items: center; margin-top: 14px; max-width: 640px; }
.conn-url .code { flex: 1 1 auto; min-width: 0; margin: 0; font: 400 15px/1.3 var(--text); letter-spacing: 0; text-transform: none; text-align: left;
                  padding: 12px 14px; background: var(--n-0); }
.conn-how .conn-note { margin-top: 10px; font-size: 14px; color: var(--n-7); }
.conn-url .btn { flex: none; white-space: nowrap; }
@media (max-width: 899px) {
  .conn-how .conn-name { font-size: 28px; }
  .conn-url { flex-wrap: wrap; }
  .conn-url .btn { width: 100%; }
}
/* Kopplingar: the system's name, and the company it reads, once */
.conn-co { display: block; font-size: 15px; color: var(--n-7); margin-top: 4px; font-family: var(--text); }
/* ---------- people: who may say yes, and the client's own admins ---------- */
.people h1 { font-size: 44px; margin-top: 12px; }
.people .dek { max-width: 56ch; }
.people-list { margin-top: 32px; background: var(--white); border-radius: 4px; padding: 4px 32px; }
.person { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 10px 32px; align-items: center; padding: 18px 0; }
.person + .person { border-top: 1px solid var(--line); }
.person-name { font-family: var(--display); font-weight: 500; font-size: 24px; line-height: 1.15; letter-spacing: -0.01em; }
.you {
  font-family: var(--text);
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--quiet);
  margin-left: 10px;
  padding: 3px 8px;
  border-radius: 999px;
  box-shadow: inset 0 0 0 1px var(--line);
  vertical-align: 4px;
}
.person-meta { color: var(--quiet); margin-top: 3px; overflow-wrap: anywhere; font-size: 15px; line-height: 1.45; }
.person-act { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: flex-end; }
.person-role { font-size: 14px; color: var(--n-7); }
.person-act .seg button { font-size: 14px; padding: 8px 14px; }
.btn--small { padding: 9px 16px; font-size: 14px; }
.btn--quiet { border-color: var(--line); color: var(--n-7); }
.linkish { all: unset; cursor: pointer; color: var(--ink); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--n-4); }
.linkish:hover { text-decoration-color: var(--ink); }
.linkish:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; border-radius: 2px; }
.invite { margin-top: 30px; background: var(--white); border-radius: 4px; padding: 24px 32px 26px; }
.invite h2 { font-family: var(--display); font-weight: 300; font-size: 32px; letter-spacing: -0.015em; line-height: 1.1; }
.invite-fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; margin-top: 18px; }
.field { display: grid; gap: 6px; }
.field input { font: inherit; font-size: 16px; padding: 12px 14px; border-radius: 4px; border: 0; background: var(--n-0); color: var(--ink); box-shadow: inset 0 0 0 1px var(--line); min-width: 0; }
.field-err { display: block; margin-top: 6px; font-size: 14px; color: var(--ink); border-left: 3px solid var(--red); padding-left: 8px; }
input[aria-invalid="true"] { border-color: var(--red); }
.field input:focus { outline: none; box-shadow: inset 0 0 0 1.5px var(--ink); }
.invite-role { display: flex; align-items: center; gap: 14px; margin-top: 18px; flex-wrap: wrap; }
.invite .answers { margin-top: 22px; }
.invite .only { margin-top: 12px; color: var(--quiet); font-size: 15px; line-height: 1.45; }
.people .device-link { margin-top: 28px; }
.people .mailed { font-size: 17px; margin-bottom: 18px; max-width: 46ch; }
@media (max-width: 899px) {
  .people h1 { font-size: 38px; }
  .people-list { margin-inline: -22px; border-radius: 0; padding: 0 22px; }
  .person { grid-template-columns: 1fr; }
  .person-act { justify-content: flex-start; }
  .person-act .seg button { padding: 8px 12px; font-size: 13px; }
  .invite { margin-inline: -22px; border-radius: 0; padding: 22px; }
  .invite-fields { grid-template-columns: 1fr; }
}
.invite-fields .field { align-content: start; }
.invite-fields .field input { height: 46px; box-sizing: border-box; }
/* people: the name carries the row; the facts readable; the links a line of their own */
.person-links { display: flex; flex-wrap: wrap; gap: 4px 18px; margin-top: 8px; }
/* a person's role is a state, not a command: navy text on a pale fill; solid navy stays for what you press */
.person-act .seg button.on { background: var(--n-1); color: var(--ink); box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--ink) 35%, transparent); }
@media (max-width: 899px) {
  /* the record's filters: a grid, not a cloud */
  /* people and devices: readable facts, the actions a thumb finds */
  .person-meta { font-size: 15px; }
}
/* ---------- what Bob put on the record this week, under Väntar på dig ---------- */
.findings { margin-top: 30px; background: var(--white); border-radius: 4px; padding: 20px 28px 18px; max-width: 880px; } /* the decision: the column holds everything under it; the warning sits with its words; the stamp says the outcome first */
.findings ul { margin-top: 8px; }
.findings--inline { margin: 22px 0 6px; padding: 16px 20px 12px; max-width: 560px; } /* inside the text column, above the day's dots */
.findings--inline li { grid-template-columns: 1fr; gap: 4px; font-size: 15px; }
.findings--here { margin: 14px 0 0; padding: 14px 20px 6px; max-width: 880px; } /* beside the decision it concerns */
.findings--here li { font-size: 15px; }
.findings li { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 18px; padding: 12px 0; border-top: 1px solid var(--line); font-size: 15px; }
.findings li span:first-child { overflow-wrap: anywhere; }
.findings .linkish { display: inline-block; margin-top: 10px; font-size: 14px; }
@media (max-width: 899px) {
  .findings { margin: 26px -22px 0; border-radius: 0; padding: 18px 22px; }
  .findings li { grid-template-columns: 1fr; gap: 4px; }
}
/* Bob's notes: red only while something is open; a settled one says who settled it */
.dot.is-quiet { background: var(--n-4); }
.findings .settled { display: block; margin-top: 4px; font-size: 13px; color: var(--n-7); }
/* ---------- your devices: add another passkey ---------- */
.qr { margin: 0; width: 184px; flex: none; background: var(--white); padding: 8px; border-radius: 4px; box-shadow: inset 0 0 0 1px var(--line); }
.qr svg { display: block; width: 100%; height: auto; }
.link-qr { display: flex; gap: 22px; align-items: center; margin-bottom: 18px; }
.link-qr .qr-how { font-size: 15px; margin-top: 6px; max-width: 34ch; }
.phone-first { margin-top: 24px; display: flex; gap: 20px; align-items: center; }
.phone-first p { max-width: 32ch; font-size: 17px; }
.phone-first + .btn, .phone-first ~ #go { margin-top: 22px; }
@media (max-width: 899px) {
  .link-qr { flex-direction: column; align-items: flex-start; }
  .phone-first { flex-direction: column; align-items: flex-start; }
}
.devices h1 { font-size: 44px; margin-top: 12px; max-width: 20ch; }
.device-link { margin-top: 28px; max-width: 640px; }
.device-link .code { font-size: 15px; letter-spacing: 0; text-transform: none; text-align: left; padding: 14px 16px; font-family: var(--text); }
.door .whose { margin-top: 14px; font-size: 16px; color: var(--ink); max-width: 46ch; } /* whose key and which company: the trust line */
.held.away { background: var(--white); } /* information, not the security notice's Shell */
.held.away a { color: var(--ink); text-underline-offset: 3px; }
.msg .linkish { font-size: inherit; }
@media (max-width: 899px) {
  .devices h1 { font-size: 34px; }
}
.device-list { margin-top: 28px; max-width: 760px; background: var(--white); border-radius: 4px; padding: 4px 32px; } /* the same card as Personer */
.device-list li { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 18px 0; font-size: 15px; }
.device-list li + li { border-top: 1px solid var(--line); }
.device-list b { font-weight: 400; color: var(--ink); }
.held { margin: 0 0 24px; padding: 14px 18px; background: var(--shell); border-radius: 4px; font-size: 15px; max-width: 760px; }
.held .label { display: block; margin-bottom: 4px; }
.door #providers { margin-top: 32px; }
.door #providers + #go { margin-top: 12px; }
.device .this-note { display: block; margin-top: 4px; color: var(--ink); }
.device-act { display: flex; gap: 16px; align-items: center; flex-wrap: wrap; }
.dev-name { display: flex; gap: 10px; align-items: end; flex-wrap: wrap; }
.dev-name .field input { height: 40px; }
.device .chip { justify-self: start; margin: 2px 0; border: 1px solid var(--n-5); color: var(--ink); background: none; }
.device-list + .msg:not(:empty) { margin-top: 14px; max-width: 760px; }
.device-list .conn-confirm, .device-list .dev-name { flex: 1 1 100%; }
.device-list .conn-confirm p { white-space: normal; }
.made .qr { width: 144px; }
.made .link-qr .quiet { margin-top: 12px; font-size: 14px; }
.devices .device-link { max-width: 760px; }
.dev-sep { font-style: normal; }
.device .chip, .device .you { font-family: var(--text); font-size: 11px; letter-spacing: .08em; text-transform: uppercase; padding: 3px 8px; border-radius: 999px; line-height: 1.3; }
@media (min-width: 900px) {
  .device-act { flex-direction: column; align-items: flex-end; gap: 0; padding-top: 2px; }
  /* a link to hand over (an invitation, a new device): one group, the code beside what to do with it */
  .device-link { display: grid; grid-template-columns: 184px minmax(0, 1fr); column-gap: 32px; align-items: start; max-width: 880px; background: var(--white); border-radius: 4px; padding: 24px 32px; }
  .device-link .link-qr { display: contents; }
  .device-link > *, .device-link .link-qr > div { grid-column: 2; }
  .device-link .qr { grid-column: 1; grid-row: 1 / span 4; box-shadow: none; padding: 0; }
  .device-link:has(> .mailed) .qr { grid-row: 2 / span 4; }
  .device-link > .mailed { grid-column: 1 / -1; }
  .device-link .code { margin-top: 18px; background: var(--n-0); }
  .device-link .answers { margin-top: 14px; }
  .device-link .only { margin-top: 14px; }
  /* people: the instructions as wide as the link they explain */
  .device-link .qr-how { max-width: 60ch; }
  /* devices: actions anchored to their device; the two badges one family */
  .device-list li { align-items: flex-start; }
}
@media (max-width: 899px) {
  .device-list li { flex-wrap: wrap; align-items: flex-start; row-gap: 6px; }
  .device-act { flex: 1 1 100%; gap: 12px; } /* on a phone the actions sit under the device, not squeezed beside it */
  .device-act .btn--text { font-size: 16px; }
  .device .this-note { font-size: 15px; }
  .device-link { margin-top: 40px; }
  .device-link .link-qr { margin-bottom: 24px; }
  .device-link .answers { margin-top: 12px; }
  .device-link .code { margin-top: 0; } /* the link field follows its instructions at the link-qr's own gap */
  .dev-when { display: block; }
  .dev-sep { display: none; }
  .dev-what { display: block; }
  .device-link .link-qr > div { order: -1; } /* who it is for, before the code */
}
/* a device a person recognises */
.device { display: grid; gap: 2px; }
.device b { font-family: var(--display); font-weight: 500; font-size: 22px; line-height: 1.15; letter-spacing: -0.01em; }
.device .you { justify-self: start; margin: 2px 0; background: var(--ink); color: var(--n-0); box-shadow: none; border: 1px solid var(--ink); } /* devices: this one is marked in ink; "ny" is a quiet note; the actions readable */
.device-list .btn { white-space: nowrap; }
.device small { color: var(--n-7); font-size: 14px; }
@media (max-width: 899px) {
  .device-list { margin-inline: -22px; border-radius: 0; padding: 0 22px; }
}
/* ---------- a person's note to Bob with a decision ---------- */
.note-field { display: grid; gap: 6px; margin-top: 24px; max-width: 640px; }
/* grows with the note, so a phone never hides its start */
.note-field textarea {
  font: inherit;
  font-size: 16px;
  line-height: 1.4;
  padding: 12px 14px;
  border-radius: 4px;
  border: 0;
  background: var(--white);
  color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--line);
  resize: vertical;
  min-height: calc(3lh + 24px);
  field-sizing: content;
  max-height: 50vh;
}
.note-field textarea:focus { outline: none; box-shadow: inset 0 0 0 1.5px var(--ink); }
.note-field small { font-size: 12px; color: var(--quiet); }
.note-field + .only { margin-top: 18px; }
/* ---------- Deepbob's own panel (/approve/admin): every client, for Deepbob's admins; an instrument, not the desk ---------- */
.admin { min-height: 100vh; background: var(--n-0); }
.admin-bar { display: flex; align-items: center; gap: 14px; padding: 18px 40px; border-bottom: 1px solid var(--line); }
.admin-bar .label { padding: 3px 9px; border-radius: 999px; box-shadow: inset 0 0 0 1px var(--line); font-size: 11px; }
.admin-who { margin-left: auto; font-size: 13px; color: var(--quiet); }
.admin-work { max-width: 1280px; margin: 0 auto; padding: 36px 40px 64px; }
.admin-door { max-width: 560px; margin: 8vh auto 0; }
.admin-door h1 { font-size: 56px; margin-top: 12px; }
.admin-head { display: flex; justify-content: space-between; align-items: flex-end; gap: 24px; }
.admin-head h1 { font-size: 48px; margin-top: 10px; }
.admin-head .count { font-size: 24px; vertical-align: 26px; color: var(--quiet); margin-left: 4px; }
.ctable { background: var(--white); border-radius: 4px; margin-top: 40px; } /* admin: the table reads as a sheet, clear of the title */
.ctable-head, .crow-head { display: grid; grid-template-columns: minmax(0, 2.6fr) 0.9fr 0.8fr minmax(0, 1.6fr) 0.8fr 0.8fr 1fr 56px; gap: 16px; align-items: center; padding: 0 24px; }
.ctable-head { letter-spacing: .08em; text-transform: uppercase; padding-top: 14px; padding-bottom: 12px; border-bottom: 1px solid var(--line); color: var(--n-7); font-size: 12px; }
.crow + .crow { border-top: 1px solid var(--line); }
.crow-head {
  all: unset;
  box-sizing: border-box;
  display: grid;
  grid-template-columns: minmax(0, 2.6fr) 0.9fr 0.8fr minmax(0, 1.6fr) 0.8fr 0.8fr 1fr 56px;
  gap: 16px;
  align-items: center;
  width: 100%;
  padding: 16px 24px;
  cursor: pointer;
  transition: background 160ms var(--ease);
  padding-block: 20px;
}
.crow-head:hover, .crow.is-open .crow-head { background: color-mix(in oklch, var(--n-1) 55%, var(--white)); }
.crow-head:focus-visible { outline: 2px solid var(--red); outline-offset: -2px; }
.c-name b { display: block; font-family: var(--display); font-weight: 400; letter-spacing: -0.01em; line-height: 1.15; font-size: 23px; }
.c-name small, .c-num small { display: block; color: var(--quiet); margin-top: 2px; overflow-wrap: anywhere; font-size: 13px; }
.c-num { font-size: 16px; font-variant-numeric: tabular-nums; }
.c-num .dot { vertical-align: 1px; }
.c-when { font-size: 14px; color: var(--n-7); }
.c-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
  box-shadow: inset 0 0 0 1px var(--line);
  display: inline-block;
  margin-left: 10px;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 12px;
  letter-spacing: .02em;
  vertical-align: middle;
  background: var(--shallow);
  color: var(--ink);
  font-family: var(--text, inherit);
  font-weight: 400;
}
.crow-body { padding: 4px 24px 24px; background: var(--white); border-top: 1px solid var(--line); padding-top: 12px; }
.cd-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); gap: 32px; }
.cd-people li, .cd-record li { display: grid; gap: 2px; border-top: 1px solid var(--line); font-size: 15px; padding: 12px 0; }
.cd-people li b { font-weight: 400; }
.cd-people small { color: var(--quiet); font-size: 13px; }
.cd-record li { grid-template-columns: 82px minmax(0, 1fr); gap: 12px; }
.cd-record small { display: block; font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--quiet); margin-bottom: 1px; }
.cd-link { margin-top: 12px; font-size: 14px; }
.empty { padding: 28px 24px; color: var(--quiet); }
.create, .made { margin-top: 24px; background: var(--white); border-radius: 4px; padding: 24px 28px 26px; }
.create h2, .made h2 { font-family: var(--display); font-weight: 300; font-size: 32px; letter-spacing: -0.015em; line-height: 1.1; }
.made { background: var(--white); box-shadow: inset 4px 0 0 var(--ink); } /* done: a receipt, not an alert */
.made > p { margin-top: 8px; font-size: 16px; max-width: 60ch; }
.made .link-qr { margin-top: 18px; align-items: flex-start; }
.made-link { margin-top: 6px; font-size: 14px; overflow-wrap: anywhere; }
.tpl-about { display: block; font-size: 13px; color: var(--quiet); margin-top: 8px; max-width: 46ch; }
.create .only { margin-top: 12px; font-size: 13px; color: var(--quiet); }
@media (max-width: 899px) {
  .admin-bar { padding: 14px 22px; }
  .admin-who { display: none; }
  .admin-work { padding: 24px 22px 48px; }
  .admin-head { flex-direction: column; align-items: flex-start; }
  .admin-head h1, .admin-door h1 { font-size: 40px; }
  .ctable { margin-inline: -22px; border-radius: 0; }
  .ctable-head { display: none; }
  .crow-head { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px 16px; padding: 16px 22px; }
  .crow-head .c-name { grid-column: 1 / -1; }
  .crow-head .c-chips::before { flex-basis: 100%; margin-bottom: 0; }
  .crow-head [data-k]::before { content: attr(data-k); display: block; font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--quiet); margin-bottom: 2px; }
  .crow-body { padding: 4px 22px 22px; }
  .cd-grid { grid-template-columns: 1fr; gap: 18px; }
  .create, .made { margin-inline: -22px; border-radius: 0; padding: 22px; }
}
/* admin: the row says it opens; the create form's fields share one height; a mail that did not go is a status */
.c-open { text-align: right; display: inline-block; justify-self: end; font-size: 13px; color: var(--ink); border: 1px solid var(--line); border-radius: 999px; padding: 5px 14px; }
.made .not-sent { margin-top: 10px; font-size: 15px; color: var(--ink); }
.crow-head:hover .c-open { border-color: var(--ink); }
.cd-record .is-example { opacity: .62; }
.made.is-unsent { box-shadow: inset 4px 0 0 var(--ink); }
.create .tpl-about { display: block; grid-column: 1 / -1; margin-top: -6px; }
/* admin: a task's heading wins over the page's; the opened client is a white sheet; its text readable; a missed mail is a red label, not a red rail */
.made.is-unsent > .label { color: var(--ink); }
.made.is-unsent > .label::before { content: ""; display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--red); margin-right: 8px; vertical-align: 1px; }
.made .made-link { font-size: 16px; background: var(--n-0); padding: 10px 12px; border-radius: 4px; max-width: 72ch; }
/* admin: one size of title; the opened client's headings legible; the form ends where its content does; the invitation link on its own ground */
.crow-body .label { font-size: 13px; color: var(--ink); }
.create .msg:empty, .made .msg:empty { min-height: 0; margin: 0; }
