/* Penholder design system. Tokens first, then components, then pages.
   Light and dark are the same tokens with different values. */

/* Plus Jakarta Sans, served from this origin (SIL OFL, see assets/fonts/OFL.txt). Loading it from
   Google would send every visitor's IP address to Google, which EU privacy law does not allow
   without consent. One variable file per script covers weights 400 to 800. */
@font-face {
  font-family: "Plus Jakarta Sans"; font-style: normal; font-weight: 400 800; font-display: swap;
  src: url("/assets/fonts/plus-jakarta-sans-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Plus Jakarta Sans"; font-style: normal; font-weight: 400 800; font-display: swap;
  src: url("/assets/fonts/plus-jakarta-sans-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  --bg: #fbfbfd;
  --bg-sunk: #f4f5f9;
  --surface: #ffffff;
  --surface-2: #f5f6fa;
  --surface-3: #eceef5;
  --border: #e5e7ef;
  --border-strong: #d3d7e3;
  --text: #0e1017;
  --text-2: #4a5163;
  --muted: #5f677a;
  --faint: #666c7b;  /* 4.5:1 or better on every light surface (was 2.8 to 3.3) */

  --accent: #4f46e5;
  --accent-2: #7c3aed;
  --accent-soft: #eef0ff;
  --accent-line: #c9cdf8;

  --money: #0e7a52;
  --money-soft: #e2f6ed;
  --danger: #c32d1c;
  --danger-soft: #fdeceb;
  --danger-fill: var(--danger);  /* filled shapes with white text on them: the delete button, the error toast */
  --warn: #92400e;
  --warn-soft: #fef3c7;

  --grad: linear-gradient(135deg, var(--accent) 0%, var(--accent-2) 100%);
  /* Filled shapes with white text on them (buttons, logos, the brand mark). In light mode the same
     gradient; dark mode needs deeper stops, white on #8b8cf7 is only 2.9:1. */
  --grad-fill: var(--grad);
  --shadow-sm: 0 1px 2px rgba(16, 20, 40, .05);
  --shadow: 0 1px 2px rgba(16, 20, 40, .05), 0 12px 28px -14px rgba(16, 20, 40, .18);
  --shadow-lg: 0 2px 4px rgba(16, 20, 40, .05), 0 28px 60px -22px rgba(79, 70, 229, .28);
  --ring: 0 0 0 3px color-mix(in srgb, var(--accent) 28%, transparent);

  --r-sm: 9px;
  --r: 13px;
  --r-lg: 20px;
  --font: "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --t-fast: .16s;
  --t: .26s;
  --ease: cubic-bezier(.22, 1, .36, 1);
  --spring: cubic-bezier(.34, 1.4, .64, 1);
  --tap: 44px;
}

/* Dark: boot.js sets data-theme before first paint, from the account's choice or else the device's setting. */
:root { color-scheme: light; }
:root[data-theme="dark"] {
    color-scheme: dark;
    --bg: #0a0b10;
    --bg-sunk: #07080c;
    --surface: #13151d;
    --surface-2: #1a1d27;
    --surface-3: #232733;
    --border: #242835;
    --border-strong: #363c4d;
    --text: #f0f2f7;
    --text-2: #b3b9c9;
    --muted: #9aa2b5;
    --faint: #878ea0;  /* 4.5:1 or better on every dark surface (was 3.7 to 4.8) */
    --accent: #8b8cf7;
    --accent-2: #a78bfa;
    --grad-fill: linear-gradient(135deg, #6061e8 0%, #7b4fe0 100%);  /* white text: 4.8 and 5.2 */
    --accent-soft: #1c1e3a;
    --accent-line: #3a3d70;
    --money: #45d497;
    --money-soft: #0f2c21;
    --danger: #ff8272;
    --danger-soft: #331817;
    --danger-fill: #d83a2a;  /* white on #ff8272 was 2.4:1; this is 6.1 */
    --warn: #fcd34d;
    --warn-soft: #3a2d0a;
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .5);
    --shadow: 0 1px 2px rgba(0, 0, 0, .5), 0 12px 28px -14px rgba(0, 0, 0, .7);
    --shadow-lg: 0 2px 4px rgba(0, 0, 0, .5), 0 28px 60px -22px rgba(0, 0, 0, .85);
}

*, *::before, *::after { box-sizing: border-box; }
/* The scrollbar's room is always kept, so the page and its header do not jump sideways
   between a page that scrolls (profile, a team) and one that does not (the teams list). */
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scrollbar-gutter: stable; }
body {
  margin: 0; min-height: 100vh; display: flex; flex-direction: column;
  font-family: var(--font); font-size: 15.5px; line-height: 1.6;
  color: var(--text); background: var(--bg);
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
main { flex: 1; }
h1, h2, h3, h4 { margin: 0; line-height: 1.15; letter-spacing: -.028em; font-weight: 700; text-wrap: balance; }
h1 { font-size: clamp(26px, 4vw, 34px); }
h2 { font-size: 20px; letter-spacing: -.02em; }
h3 { font-size: 15.5px; font-weight: 650; letter-spacing: -.012em; }
p { margin: 0; }
a { color: inherit; }
a:not([class]) { color: var(--accent); text-underline-offset: 3px; }
img { max-width: 100%; }
[hidden] { display: none !important; }
::selection { background: var(--accent-soft); color: var(--accent); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* One stacking scale for everything that floats. Dialogs use the browser's top layer, above all of these. */
:root { --z-drag: 20; --z-dropdown: 30; --z-nav: 50; --z-sheet: 60; --z-skip: 100; --z-ghost: 150; --z-toast: 200; }
.skip { position: absolute; left: -9999px; top: 8px; z-index: var(--z-skip); background: var(--surface); padding: 8px 14px; border-radius: var(--r-sm); }
.skip:focus { left: 12px; }

/* ------------------------------------------------------------ layout */
/* padding-inline, not the padding shorthand: .wrap shares elements with .page, .foot-grid and
   .foot-bottom, and a shorthand here (or in the phone query below) zeroed their vertical padding. */
.wrap { width: 100%; max-width: 1120px; margin: 0 auto; padding-inline: 24px; }
.narrow { width: 100%; max-width: 470px; margin: 0 auto; padding-inline: 24px; }
.page { padding-top: 26px; padding-bottom: 60px; }
.row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.grow { flex: 1; min-width: 0; }
.center { text-align: center; }
.center-row { justify-content: center; }
.muted { color: var(--muted); }
.faint { color: var(--faint); font-size: 13px; }
.hint { color: var(--faint); font-size: 12.5px; margin-top: 6px; }
.sub { margin: 6px 0 22px; font-size: 14px; }
.small-gap { margin-top: 18px; font-size: 14px; }
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 14px; }
.stack > * + * { margin-top: 14px; }
.divider { height: 1px; background: var(--border); border: 0; margin: 22px 0; }
.page-head { padding: 6px 0 20px; }
.page-head p.muted { margin-top: 6px; font-size: 14.5px; }
.section { margin-top: 30px; }
.section-title { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; flex-wrap: wrap; }
.section-title h2 { font-size: 17px; }

/* ------------------------------------------------------------ nav */
.nav {
  position: sticky; top: 0; z-index: var(--z-nav);
  background: color-mix(in srgb, var(--bg) 84%, transparent);
  backdrop-filter: saturate(180%) blur(14px); -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--border);
}
.nav .wrap { display: flex; align-items: center; justify-content: space-between; height: 60px; gap: 12px; }
.brand { display: inline-flex; align-items: center; gap: 9px; text-decoration: none; font-weight: 750; font-size: 16.5px; letter-spacing: -.028em; white-space: nowrap; }
.brand-mark {
  width: 26px; height: 26px; border-radius: 8px; flex: none; color: #fff;
  background: var(--grad-fill); display: grid; place-items: center;
  box-shadow: 0 3px 10px -3px color-mix(in srgb, var(--accent) 60%, transparent);
  transition: transform var(--t) var(--spring);
}
.brand:hover .brand-mark { transform: rotate(-6deg) scale(1.06); }
.nav-links { display: flex; align-items: center; gap: 6px; }
.nav-links .btn.active { color: var(--text); background: var(--surface-2); }
.nav .brand { padding-block: 9px; }
/* The tap circle is wider than the avatar; pull it out so the avatar lines up with the page edge. */
.nav-me { display: grid; place-items: center; width: var(--tap); height: var(--tap); border-radius: 50%; text-decoration: none; margin-right: -8px; }

/* ------------------------------------------------------------ buttons */
.btn {
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 40px; padding: 9px 16px; border: 1px solid transparent; border-radius: var(--r-sm);
  font: inherit; font-size: 14px; font-weight: 600; letter-spacing: -.008em;
  text-decoration: none; white-space: nowrap; cursor: pointer; color: var(--text); background: none;
  transition: background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease),
              color var(--t-fast) var(--ease), transform var(--t-fast) var(--spring), box-shadow var(--t) var(--ease);
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
.btn:active { transform: scale(.97); }
.btn:focus-visible { outline: none; box-shadow: var(--ring); }
.btn:disabled { opacity: .45; cursor: not-allowed; transform: none; }
.btn.is-busy { color: transparent !important; pointer-events: none; }
.btn.is-busy::after {
  content: ""; position: absolute; width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid currentColor; border-color: var(--muted) transparent var(--muted) transparent;
  animation: spin .7s linear infinite;
}
.btn-primary { background: var(--grad-fill); color: #fff; box-shadow: 0 4px 14px -6px color-mix(in srgb, var(--accent) 70%, transparent); }
.btn-primary.is-busy::after { border-color: #fff transparent #fff transparent; }
.btn-ghost { color: var(--muted); }
.btn-ghost:hover { background: var(--surface-2); color: var(--text); }
.btn-outline { background: var(--surface); border-color: var(--border-strong); }
.btn-outline:hover { background: var(--surface-2); }
.btn-danger { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 40%, transparent); }
.btn-danger:hover { background: var(--danger-soft); }
.btn-danger-solid { background: var(--danger-fill); color: #fff; }
.btn-sm { min-height: 36px; padding: 7px 13px; font-size: 13px; }
.btn-lg { min-height: 48px; padding: 13px 24px; font-size: 15.5px; border-radius: var(--r); }
.btn-block { width: 100%; white-space: normal; }
.btn-icon { width: 40px; min-width: 40px; padding: 0; }
@media (pointer: coarse) {
  .btn, .btn-sm { min-height: var(--tap); }
  .btn-icon { width: var(--tap); min-width: var(--tap); }
}

/* ------------------------------------------------------------ forms */
label, .label { display: block; font-size: 13px; font-weight: 600; margin-bottom: 7px; color: var(--text-2); }
input[type=text], input[type=email], input[type=password], input[type=number], input[type=search], textarea, select, .picker > summary {
  width: 100%; min-height: 44px; padding: 10px 13px;
  font: inherit; font-size: 16px; color: var(--text); /* 16px stops iOS zooming on focus */
  background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--r-sm); appearance: none;
  transition: border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
input::placeholder, textarea::placeholder { color: var(--faint); }
select, .picker > summary {
  padding-right: 34px; cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 17px) 51%, calc(100% - 12px) 51%; background-size: 5px 5px; background-repeat: no-repeat;
}
textarea { resize: vertical; min-height: 80px; line-height: 1.5; }
input:focus, textarea:focus, select:focus, .picker > summary:focus { outline: none; border-color: var(--accent); box-shadow: var(--ring); }
input[readonly] { background: var(--surface-2); color: var(--muted); }
input[type=file] { font: inherit; font-size: 14px; max-width: 100%; }
.field { margin-bottom: 16px; }
.field-row { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.field-row > .field { flex: 1; min-width: 160px; margin-bottom: 0; }
/* A yes or no field: three pills in one track. The checked pill lifts; Yes takes the accent. */
.seg { display: inline-flex; flex-wrap: wrap; gap: 4px; padding: 4px; max-width: 100%; border: 1px solid var(--border-strong); border-radius: 12px; background: var(--surface-2); }
.seg label { position: relative; display: inline-flex; margin: 0; font-weight: inherit; cursor: pointer; }
.seg input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.seg span { display: inline-flex; align-items: center; justify-content: center; min-width: 64px; min-height: 34px; padding: 0 14px; border-radius: 9px; font-size: 14px; font-weight: 600; color: var(--muted); transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease); }
.seg label:hover span { color: var(--text); }
.seg input:checked + span { background: var(--surface); color: var(--text); box-shadow: var(--shadow-sm); }
.seg input[value="yes"]:checked + span { background: var(--accent-soft); color: var(--accent); }
.seg input:focus-visible + span { box-shadow: var(--ring); }
@media (pointer: coarse) { .seg span { min-height: var(--tap); } }
.inline-form { display: flex; gap: 8px; align-items: stretch; flex-wrap: wrap; }
.inline-form input { flex: 1; min-width: 0; }

/* ------------------------------------------------------------ surfaces */
.card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r); }
.card-pad { padding: 20px; }
.panel { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--shadow); padding: 30px; }
.auth { padding-top: 48px; padding-bottom: 56px; }
.tile { display: block; padding: 18px; text-decoration: none; transition: transform var(--t) var(--ease), box-shadow var(--t) var(--ease), border-color var(--t) var(--ease); }
.tile:hover { transform: translateY(-2px); box-shadow: var(--shadow); border-color: var(--accent-line); }
.tile h3 { margin-bottom: 4px; overflow-wrap: anywhere; }
.list > * + * { border-top: 1px solid var(--border); }
.list-item { padding: 13px 16px; display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.list-item > .menu { margin-left: auto; }  /* a row's menu always sits at its right end */
.empty { text-align: center; padding: 44px 22px; color: var(--muted); }
.empty h3 { margin-bottom: 6px; color: var(--text); font-size: 16px; }
.empty .btn { margin-top: 14px; }
.loading { display: flex; align-items: center; gap: 10px; justify-content: center; padding: 64px 0; color: var(--faint); }
.spinner { width: 18px; height: 18px; border-radius: 50%; border: 2px solid var(--border-strong); border-top-color: var(--accent); animation: spin .7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

.notice { display: flex; gap: 9px; padding: 11px 14px; border-radius: var(--r-sm); font-size: 14px; font-weight: 500; margin-bottom: 16px; }
.notice-error { background: var(--danger-soft); color: var(--danger); }
.notice-ok { background: var(--money-soft); color: var(--money); }
.notice-info { background: var(--accent-soft); color: var(--accent); }
.notice-warn { background: var(--warn-soft); color: var(--warn); }

.tag { display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px; border-radius: 20px; font-size: 12px; font-weight: 650; white-space: nowrap; }
.tag-soft { background: var(--surface-3); color: var(--text-2); }
.tag-accent { background: var(--accent-soft); color: var(--accent); }
.tag-money { background: var(--money-soft); color: var(--money); }
.tag-warn { background: var(--warn-soft); color: var(--warn); }
.tag-danger { background: var(--danger-soft); color: var(--danger); }

.avatar {
  width: 28px; height: 28px; border-radius: 50%; flex: none; object-fit: cover;
  background: var(--accent-soft); color: var(--accent); display: inline-grid; place-items: center;
  font-size: 11.5px; font-weight: 750; overflow: hidden;
}
.avatar-empty { background: var(--surface-3); color: var(--faint); }
.avatar-sm { width: 22px; height: 22px; font-size: 10.5px; }
.avatar-lg { width: 76px; height: 76px; font-size: 26px; }
.faces { display: flex; }
.faces .avatar { width: 24px; height: 24px; font-size: 11px; margin-left: -4px; border: 2px solid var(--surface); }
.faces .avatar:first-child { margin-left: 0; }
.faces span.avatar { box-shadow: inset 0 0 0 1px var(--accent-line); }  /* initials read as faces, not loose letters */
/* Under a team, project or topic name: overlapping faces and who holds the pen. */
.faces-lg .avatar { width: 30px; height: 30px; font-size: 10.5px; margin-left: -6px; border-color: var(--bg); }
.faces-lg .avatar:first-child { margin-left: 0; }
.head-meta { display: flex; align-items: center; gap: 8px 14px; flex-wrap: wrap; margin-top: 8px; }
.pen-line { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 14px; color: var(--muted); }
.pen-line svg { color: var(--accent); flex: none; }
.pen-line strong { color: var(--text); font-weight: 650; }
.pen-line > span:not(.tag) { font-size: inherit; line-height: inherit; }  /* counts read at the pen's size and baseline */
/* The counts after the pen: a dot drawn before each, so a wrapped line never starts with "," or "·". On phones
   they stack under the pen instead. */
.pen-line > .pen-count::before { content: "·"; margin-right: 6px; }
@media (max-width: 640px) {
  .pen-line { flex-direction: column; align-items: flex-start; gap: 2px; }
  .pen-line > .pen-count::before { content: none; }
}
/* "You hold the pen" is a button that reads as text: a dotted underline says it opens something. */
.pen-who { position: relative; display: inline-flex; align-items: center; gap: 6px; padding: 2px 6px; margin: -2px -6px; border: 0; border-radius: 8px; background: none; color: inherit; font: inherit; cursor: pointer; }
.pen-who::before { content: ""; position: absolute; inset: -8px -2px; }
.pen-who strong { text-decoration: underline dotted var(--faint); text-underline-offset: 3px; }
.pen-who:hover { background: var(--accent-soft); }
.pen-who:hover strong { color: var(--accent); }
.pen-who:focus-visible { outline: none; box-shadow: var(--ring); }
.pen-info ul { display: grid; gap: 8px; margin: 4px 0 0; padding-left: 20px; }
.pen-info .faint { margin-top: 14px; }
.modal-body:has(.pen-info) .modal-actions { justify-content: center; }
.section-title.start { justify-content: flex-start; }
.history-more { margin-top: 10px; }
.logo { width: 40px; height: 40px; border-radius: 11px; flex: none; object-fit: cover; display: inline-grid; place-items: center; background: var(--grad-fill); color: #fff; font-weight: 750; font-size: 14px; overflow: hidden; }
.logo-lg { width: 64px; height: 64px; border-radius: 16px; font-size: 22px; }
.logo-sm { width: 28px; height: 28px; border-radius: 8px; font-size: 12px; }
/* The colour is for initials. An uploaded picture shows as it is: a transparent logo keeps its transparency
   instead of sitting on purple. */
img.logo, img.avatar, img.tile-pic { background: transparent; box-shadow: none; }

.crumbs { display: flex; align-items: center; gap: 7px; font-size: 13px; color: var(--muted); flex-wrap: wrap; margin-bottom: 12px; }
.crumbs a { text-decoration: none; }
.crumbs a:hover { color: var(--accent); }
.crumbs span { color: var(--faint); }

.big-check { width: 64px; height: 64px; border-radius: 50%; margin: 0 auto 16px; display: grid; place-items: center; font-size: 28px; background: var(--money-soft); color: var(--money); }
.error-page { padding-top: 76px; padding-bottom: 76px; }
.error-code { font-size: 64px; font-weight: 800; letter-spacing: -.05em; color: var(--faint); }
.error-page p { margin: 8px 0 24px; }

/* toasts */
.toasts { position: fixed; left: 50%; bottom: max(16px, env(safe-area-inset-bottom)); transform: translateX(-50%); z-index: var(--z-toast); display: flex; flex-direction: column; gap: 8px; width: min(440px, calc(100vw - 24px)); pointer-events: none; }
.toast { pointer-events: auto; padding: 12px 16px; border-radius: var(--r); background: var(--text); color: var(--bg); font-size: 14px; font-weight: 550; box-shadow: var(--shadow-lg); animation: rise .3s var(--ease); }
.toast-error { background: var(--danger-fill); color: #fff; }
@keyframes rise { from { opacity: 0; transform: translateY(10px); } }

/* dialogs */
dialog.modal { border: 1px solid var(--border); padding: 0; border-radius: var(--r-lg); background: var(--surface); color: var(--text); box-shadow: var(--shadow-lg); width: min(520px, calc(100vw - 24px)); max-height: calc(100dvh - 40px); }
dialog.modal::backdrop { background: rgba(8, 10, 20, .5); backdrop-filter: blur(2px); }
/* Dialogs pop in, and out a little quicker. @starting-style is the opening's first frame. Closing
   keeps the dialog in the top layer (overlay, display) while it fades, where a browser can; dialog()
   in app.js removes it after. Browsers without either open or close at once. */
dialog.modal[open], dialog.modal[open]::backdrop { transition: opacity var(--t) var(--ease), transform var(--t) var(--spring); }
@supports (overlay: auto) {
  dialog.modal, dialog.modal::backdrop { opacity: 0; transition: opacity .14s var(--ease), transform .14s var(--ease), overlay .14s allow-discrete, display .14s allow-discrete; }
  dialog.modal { transform: scale(.97); }
  dialog.modal[open], dialog.modal[open]::backdrop { opacity: 1; transform: none; }
}
/* After the rules above: same specificity, so the later one wins. */
@starting-style {
  dialog.modal[open] { opacity: 0; transform: translateY(8px) scale(.94); }
  dialog.modal[open]::backdrop { opacity: 0; }
}
.modal-body { padding: 24px; overflow-y: auto; }
.modal-body h2 { margin-bottom: 8px; }
.modal-body > p { color: var(--muted); font-size: 14.5px; margin-bottom: 16px; }
.modal-actions { display: flex; gap: 8px; justify-content: flex-end; flex-wrap: wrap; margin-top: 18px; }
.modal-img { display: block; width: 100%; height: auto; border-radius: var(--r); }

/* footer: the landing page only */
footer.site { border-top: 1px solid var(--border); background: var(--bg-sunk); color: var(--faint); font-size: 13px; }
.foot-grid { display: grid; grid-template-columns: 1.6fr 1fr 1.3fr 1fr; gap: 32px; padding-top: 48px; padding-bottom: 30px; }
.foot-grid h2 { font-size: 15px; font-weight: 700; letter-spacing: -.01em; color: var(--text); margin-bottom: 8px; }
.foot-grid a:not(.brand) { display: block; color: var(--muted); text-decoration: none; font-size: 13px; padding: 3px 0; }
.foot-grid a:not(.brand):hover { color: var(--accent); }
.foot-brand .brand { font-size: 23px; gap: 12px; color: var(--text); }
.foot-brand .brand-mark { width: 38px; height: 38px; border-radius: 11px; }
.foot-brand .brand-mark svg { width: 22px; height: 22px; }
.foot-brand p { color: var(--text-2); font-size: 15.5px; line-height: 1.55; margin-top: 14px; max-width: 34ch; }
.foot-bottom { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; padding-top: 16px; padding-bottom: 20px; border-top: 1px solid var(--border); }

/* essays */
.narrow-read { max-width: 700px; margin: 0 auto; padding: 48px 24px 64px; }
.back { font-size: 14px; color: var(--muted); text-decoration: none; }
.essay h1 { margin-top: 22px; font-size: clamp(30px, 4.6vw, 40px); letter-spacing: -.034em; }
.essay .lede { font-size: 18.5px; color: var(--muted); margin-top: 14px; line-height: 1.55; }
.prose { margin-top: 32px; font-size: 16.5px; line-height: 1.75; }
.prose h2 { margin-top: 34px; margin-bottom: 10px; font-size: 22px; }
.prose p, .prose ul, .prose ol { margin-top: 14px; }
.prose ul, .prose ol { padding-left: 22px; }
.prose li { margin: 6px 0; }
.prose blockquote { margin: 18px 0; padding: 12px 20px; border-left: 3px solid var(--accent-line); background: var(--surface-2); border-radius: 0 var(--r-sm) var(--r-sm) 0; }
.prose blockquote p { margin: 4px 0; }
/* A table on a legal page: it scrolls inside its own box rather than pushing the page sideways. */
.table-wrap { overflow-x: auto; margin-top: 16px; border: 1px solid var(--border); border-radius: var(--r); }
.prose table { border-collapse: collapse; width: 100%; min-width: 620px; font-size: 14.5px; }
.prose th, .prose td { text-align: left; padding: 11px 13px; border-bottom: 1px solid var(--border); vertical-align: top; }
.prose thead th { background: var(--surface-2); font-size: 12px; letter-spacing: .05em; text-transform: uppercase; color: var(--faint); font-weight: 700; }
.prose tbody tr:last-child td { border-bottom: 0; }
/* A legal page reads in a narrow column; its table needs more than that, so on a wide screen it leans
   out of the column on both sides instead of squeezing five columns into 620px. */
@media (min-width: 1040px) {
  .narrow-read .table-wrap { width: 132%; margin-left: -16%; }
}
.prose code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: .88em; font-weight: 500; padding: 1px 6px; border-radius: 6px; background: var(--surface-2); border: 1px solid var(--border); }
.essay-cta { margin-top: 44px; padding: 24px; }
.essay-cta p { color: var(--muted); margin: 8px 0 16px; }
.essay-more { margin-top: 32px; }
.essay-more h2 { font-size: 15px; color: var(--faint); text-transform: uppercase; letter-spacing: .08em; margin-bottom: 8px; }
.essay-more a { display: block; padding: 8px 0; color: var(--accent); text-decoration: none; font-weight: 600; }

/* legal pages */
.legal .updated { color: var(--faint); font-size: 14px; margin-top: 8px; }
.ident { margin-top: 16px; }
/* A grid, so a long value (the registered office) stays in its column instead of dropping under the label. */
.ident div { display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: 2px 12px; padding: 10px 0; border-bottom: 1px solid var(--border); }
.ident div:last-child { border-bottom: 0; }
.ident dt { color: var(--muted); }
.ident dd { margin: 0; font-weight: 600; overflow-wrap: anywhere; }
@media (max-width: 520px) { .ident div { grid-template-columns: 1fr; } }
.foot-legal { display: flex; flex-wrap: wrap; gap: 4px 16px; }
.foot-legal a { color: var(--muted); text-decoration: none; }
.foot-legal a:hover { color: var(--accent); }

/* billing: invoices list and the sign-up human check */
.invoice-title { font-size: 15px; margin-top: 22px; }
.invoice-list { list-style: none; padding: 0; margin: 8px 0 0; }
.invoice-list li { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; padding: 10px 0; border-top: 1px solid var(--border); font-size: 14px; }
.invoice-amount { font-weight: 600; font-variant-numeric: tabular-nums; }
.invoice-list a { margin-left: auto; }
/* The human check sits centred on top; the form under it (#gate) appears once it passes. */
.turnstile { display: flex; justify-content: center; margin: 4px 0 18px; min-height: 65px; }
#gate:not([hidden]) { animation: rise .45s var(--ease); }
/* Password fields: an eye to show what you typed, and on sign-up a strength bar under the box. */
.pw-wrap { position: relative; }
.pw-wrap input { padding-right: 50px; }
.pw-eye { position: absolute; top: 50%; right: 2px; transform: translateY(-50%); width: var(--tap); height: var(--tap); display: grid; place-items: center; padding: 0; border: 0; border-radius: var(--r-sm); background: none; color: var(--faint); cursor: pointer; }
.pw-eye:hover, .pw-eye:focus-visible { color: var(--text); }
.pw-eye svg { width: 20px; height: 20px; }
.pw-eye[aria-pressed="true"] .eye-open, .pw-eye[aria-pressed="false"] .eye-shut { display: none; }
.meter { height: 4px; margin: 6px 2px 0; border-radius: 99px; background: var(--border); overflow: hidden; }
.meter i { display: block; height: 100%; width: calc(var(--score, 0) * 25%); background: var(--meter, var(--danger)); border-radius: inherit; transition: width .3s var(--ease), background-color .3s; }
.meter-row { display: flex; justify-content: space-between; gap: 12px; }
.meter-row b { color: var(--meter, var(--faint)); font-weight: 650; }
/* The sign-up terms checkbox: the whole line is the tap target, not just the box. */
.consent { display: flex; align-items: flex-start; gap: 10px; margin: 2px 0 16px; padding: 6px 0; font-size: 14px; font-weight: 400; color: var(--muted); cursor: pointer; }
.consent input { width: 18px; height: 18px; margin: 2px 0 0; flex: none; accent-color: var(--accent); cursor: pointer; }
.or { display: flex; align-items: center; gap: 12px; margin: 18px 0 14px; color: var(--faint); font-size: 13px; }
.or::before, .or::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.google-btn svg { width: 18px; height: 18px; flex: none; }
.btn.is-disabled { opacity: .45; cursor: not-allowed; }
/* A faded gradient read as broken (white on pale lavender, 1.8:1); a quiet surface reads as "not yet". */
.btn-primary.is-disabled { opacity: 1; background: var(--surface-3); color: var(--faint); box-shadow: none; }
/* Create account and Google only look disabled, so a click can shake the box that is missing. */
.consent.needs { color: var(--text); }
.consent.needs input { outline: 2px solid var(--accent); outline-offset: 2px; }
.consent.shake { animation: shake .45s var(--ease); }
@keyframes shake { 15% { transform: translateX(-7px); } 35% { transform: translateX(6px); } 55% { transform: translateX(-4px); } 75% { transform: translateX(2px); } }
.start-plan h1 { font-size: clamp(22px, 4vw, 28px); }
.start-plan > * + * { margin-top: 14px; }

/* ------------------------------------------------------------ app pieces */
.head-row { display: flex; align-items: center; gap: 14px; min-width: 0; }
/* In a page head the picture sits at the top, beside the title, not floating in the middle of a description. */
.page-head .head-row { align-items: flex-start; }
.page-head .head-row > .logo, .page-head .head-row > .logo-edit { margin-top: 4px; }
.head-row h1 { overflow-wrap: anywhere; }
.pen-card { display: flex; gap: 12px; align-items: center; padding: 12px 16px; border-radius: var(--r); background: var(--surface-2); border: 1px solid var(--border); flex-wrap: wrap; }
.pen-card.mine { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent); }
.pen-card .grow { flex: 1 1 220px; }
.pen-glyph { width: 30px; height: 30px; border-radius: 9px; display: grid; place-items: center; background: var(--grad-fill); color: #fff; flex: none; }
.tile-meta { display: flex; align-items: center; gap: 8px; margin-top: 12px; }
.tile-meta .tag { margin-left: auto; }
.pips { display: flex; gap: 4px; margin-top: 12px; flex-wrap: wrap; }
.pip { width: 22px; height: 5px; border-radius: 3px; background: var(--surface-3); }
.pip.on { background: var(--grad); }
.tile-tags { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 10px; }

/* the topic */
.toolbar { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
/* The list does not clip, so a dragged row and an item's menu reach past its edges; its end rows round with the card. */
.slots { overflow: visible; }
.slots > :first-child { border-top-left-radius: inherit; border-top-right-radius: inherit; }
.slots > :last-child { border-bottom-left-radius: inherit; border-bottom-right-radius: inherit; }
.slot { display: flex; gap: 12px; align-items: flex-start; padding: 14px 16px; background: var(--surface); transition: background var(--t-fast) var(--ease), box-shadow var(--t) var(--ease); }
.slot + .slot { border-top: 1px solid var(--border); }
.slot.below .slot-title { color: var(--text-2); }
.slot-n { width: 26px; height: 26px; border-radius: 8px; flex: none; margin-top: 1px; display: grid; place-items: center; font-size: 12px; font-weight: 750; background: var(--accent-soft); color: var(--accent); font-variant-numeric: tabular-nums; }
.slot.below .slot-n { background: var(--surface-3); color: var(--faint); }
.slot .slot-n:empty { background: none; }
.handle {
  width: 32px; height: 40px; margin: -7px -4px -7px -8px; flex: none; border: 0; background: none; border-radius: 8px;
  display: grid; place-items: center; color: var(--faint); cursor: grab; touch-action: none;
}
.handle:hover { color: var(--text); background: var(--surface-2); }
.handle:active { cursor: grabbing; }
.slot.dragging { position: relative; z-index: var(--z-drag); box-shadow: var(--shadow-lg); background: var(--surface); }
.slots.is-dragging .slot:not(.dragging) { transition: transform .18s var(--ease); }
.thumb { width: 56px; height: 56px; flex: none; border-radius: 10px; object-fit: cover; background: var(--surface-3); border: 1px solid var(--border); cursor: zoom-in; padding: 0; overflow: hidden; }
.thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.slot-body { flex: 1; min-width: 0; }
.slot-title { font-weight: 640; font-size: 15px; letter-spacing: -.012em; overflow-wrap: anywhere; }
.slot-why { color: var(--text-2); font-size: 13.5px; margin-top: 4px; line-height: 1.5; padding-left: 10px; border-left: 2px solid var(--accent-line); overflow-wrap: anywhere; }
.slot-why.none { color: var(--faint); font-style: italic; border-left-color: var(--border); }
.slot-meta { display: flex; gap: 7px; flex-wrap: wrap; margin-top: 8px; align-items: center; font-size: 12.5px; color: var(--faint); }
/* The item's field values, on a line of their own under the owner. */
.slot-fields { display: flex; gap: 7px; flex-wrap: wrap; margin-top: 6px; }
.unowned { font-size: 12px; font-weight: 550; color: var(--faint); padding: 2px 8px; border-radius: 20px; border: 1px dashed var(--border-strong); }
.slot-acts { display: flex; gap: 4px; align-items: center; flex: none; }
.flag-note { margin-top: 8px; font-size: 13px; padding: 7px 10px; border-radius: var(--r-sm); background: var(--warn-soft); color: var(--warn); }
.asked-note { background: var(--accent-soft); color: var(--accent); }
/* topic.js: what waits for the pen holder. On a phone the buttons wrap under the words. */
.ask { display: flex; gap: 10px; align-items: flex-start; flex-wrap: wrap; padding: 10px 0; font-size: 13.5px; }
.ask + .ask { border-top: 1px solid var(--border); }
.ask .thumb { width: 40px; height: 40px; border-radius: 8px; }
.ask .log-text { flex: 1 1 180px; }
.ask .details { color: var(--text-2); }
.ask-who { display: block; margin-top: 2px; color: var(--faint); font-size: 12.5px; }
.ask-acts { display: flex; gap: 6px; margin-left: auto; }

.line-marker { display: flex; align-items: center; gap: 10px; margin: 14px 0; color: var(--accent); font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; }
.line-marker::before, .line-marker::after { content: ""; height: 2px; background: var(--accent); flex: 1; border-radius: 2px; }
.line-controls { display: inline-flex; align-items: center; gap: 4px; text-transform: none; letter-spacing: 0; }
.line-controls .btn { color: var(--accent); font-size: 20px; line-height: 1; font-weight: 600; }

.menu { position: relative; }
.menu > summary { list-style: none; }
.menu > summary::-webkit-details-marker { display: none; }
.menu-list { position: absolute; right: 0; top: calc(100% + 4px); z-index: var(--z-dropdown); min-width: 210px; max-width: calc(100vw - 32px); padding: 6px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--r); box-shadow: var(--shadow-lg); }
.menu-list button, .menu-list a { display: flex; width: 100%; align-items: center; gap: 8px; text-align: left; padding: 10px 12px; min-height: 40px; border: 0; background: none; font: inherit; font-size: 14px; color: var(--text); border-radius: 8px; cursor: pointer; text-decoration: none; }
.menu-list button:hover, .menu-list a:hover { background: var(--surface-2); }
.menu-list .danger { color: var(--danger); }
.menu-list .phone-only { display: none; }  /* Request done, Move up, Move down: phones only, see below */
.menu-list hr { border: 0; border-top: 1px solid var(--border); margin: 4px 0; }
.menu-list.menu-start { right: auto; left: 0; }                   /* app.js: no room on the left */
.menu-list.menu-up { top: auto; bottom: calc(100% + 4px); }      /* app.js: no room below */

/* personPicker in app.js: a details dropdown over a radio group */
.picker { position: relative; }
.picker > summary, .picker-opt { -webkit-tap-highlight-color: transparent; }
.picker > summary { display: flex; align-items: center; list-style: none; }
.picker > summary::-webkit-details-marker { display: none; }
.picker-face { display: flex; align-items: center; gap: 8px; min-width: 0; }
.picker-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.picker-list { position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: var(--z-dropdown); max-height: 264px; overflow-y: auto; padding: 6px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--r); box-shadow: var(--shadow-lg); }
.picker-list.picker-up { top: auto; bottom: calc(100% + 4px); }  /* app.js: more room above */
.picker-opt { position: relative; margin: 0; padding: 9px 10px; border-radius: 8px; font-size: 14.5px; font-weight: 500; color: var(--text); cursor: pointer; }
.picker-opt input { position: absolute; opacity: 0; pointer-events: none; }
.picker-opt:hover { background: var(--surface-2); }
.picker-opt:has(:checked) { background: var(--accent-soft); color: var(--accent); }
.picker-opt:has(:focus-visible) { box-shadow: var(--ring); }

.filters-bar { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.chip { display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px; border-radius: 20px; font-size: 12.5px; font-weight: 600; background: var(--surface-2); border: 1px solid var(--border); color: var(--text-2); cursor: pointer; font-family: inherit; min-height: 32px; }
.chip.on { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent); }
.value-pill { display: inline-flex; gap: 4px; padding: 2px 8px; border-radius: 20px; font-size: 11.5px; font-weight: 600; background: var(--surface-3); color: var(--text-2); }

.logline { display: flex; gap: 10px; padding: 9px 0; font-size: 13.5px; align-items: flex-start; }
.logline + .logline { border-top: 1px solid var(--border); }
.logline .btn { margin: -6px 0; }
/* The sentence flows as one paragraph. Separate flex items for who, action and
   subject turned into four skinny columns on a phone. */
.log-text { flex: 1 1 0; min-width: 0; margin: 0; overflow-wrap: anywhere; line-height: 1.5; }
.log-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent-line); flex: none; margin-top: 8px; }
.logline .when { margin-left: auto; color: var(--faint); font-size: 12.5px; white-space: nowrap; }
.logline .details { color: var(--faint); }

.danger-zone { border-color: color-mix(in srgb, var(--danger) 35%, var(--border)); }
.danger-zone h2 { color: var(--danger); }
.danger-zone .btn { white-space: normal; text-align: center; }
/* minmax(0, 1fr): a long unbreakable label must not widen every card past the screen */
.settings-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; max-width: 720px; }
.upload-row { display: flex; gap: 16px; align-items: center; flex-wrap: wrap; }
.plan { display: flex; gap: 10px; flex-wrap: wrap; }
.plan .btn { flex: 1; min-width: 180px; }
.plan-list { list-style: none; padding: 0; margin: 10px 0 0; }
.plan-list li { display: flex; align-items: center; gap: 12px; padding: 12px 0; border-top: 1px solid var(--border); }
.plan-list .grow { display: flex; flex-direction: column; min-width: 0; gap: 2px; font-size: 14px; }
.plan-list a { font-size: 14px; white-space: nowrap; }

/* reveal: only hidden once boot.js has proved JS runs */
.js .reveal { opacity: 0; transform: translateY(16px); }
.js .reveal.in { opacity: 1; transform: none; transition: opacity .6s var(--ease) var(--d, 0ms), transform .6s var(--ease) var(--d, 0ms); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
  .js .reveal { opacity: 1; transform: none; }
}

@media (max-width: 720px) {
  .foot-grid { grid-template-columns: 1fr; gap: 20px; padding-top: 32px; padding-bottom: 20px; }
  /* Links flow in a row under their heading: three stacked columns made the footer taller than the screen. */
  .foot-grid > div:not(.foot-brand) { display: flex; flex-wrap: wrap; column-gap: 20px; }
  .foot-grid h2 { flex-basis: 100%; }
}

@media (max-width: 640px) {
  .wrap, .narrow { padding-inline: 16px; }
  .nav .wrap { height: 56px; }
  .nav-links { gap: 2px; }
  .nav-links .btn-sm { padding: 7px 9px; }
  .nav-long { display: none; }
  .page { padding-top: 18px; }
  .panel { padding: 22px 18px; }
  .card-pad { padding: 16px; }
  .auth { padding-top: 24px; }
  .slot { padding: 12px; gap: 10px; }
  .thumb { width: 48px; height: 48px; }
  .slot-body { flex: 1 1 0; }
  /* The owner, fields and notes use the width under the handle and number too, instead of one word a line.
     66px is the handle (20) and number (26) with their gaps; a row with a picture keeps its column. */
  .slot:not(:has(.thumb)) :is(.slot-meta, .slot-fields, .flag-note, .asked-note) { margin-left: -66px; }
  /* A row keeps only its menu on phones: the arrows and Done had their own row and made every item
     twice as tall. They are the first entries in the menu instead; dragging the handle still works. */
  .slot-acts { margin: -6px -6px 0 0; }
  .slot-acts > .btn { display: none; }
  .menu-list .phone-only { display: flex; }
  .narrow-read { padding: 30px 16px 48px; }
  .foot-bottom { flex-direction: column; gap: 4px; }
  .list-item .grow { overflow-wrap: anywhere; }  /* rows hold a name and a tag now, so they stay on one line */
  .inline-form .btn { flex: 1 1 100%; }
  /* The team page's toolbar drops under the title on its own row; project and topic heads keep theirs beside the text. */
  .page-head .toolbar { width: 100%; }
  .modal-body { padding: 20px 18px; }
  .brand { font-size: 15.5px; }
}

/* drag and drop drop target */
.slot.drop-before { box-shadow: inset 0 3px 0 var(--accent); }
.slot.drop-after { box-shadow: inset 0 -3px 0 var(--accent); }
.slot.dragging { transition: none; opacity: .96; }

/* The last two blocks sit at the end on purpose: they override base rules above. */
@media (max-width: 360px) {
  .nav .wrap { gap: 6px; }
  .brand { gap: 7px; }
  .nav-links .btn-sm { padding: 7px 6px; }
}

/* Touch screens. Text links keep their look; padding with a matching negative
   margin gives them a finger-sized target without moving anything. */
@media (pointer: coarse) {
  .menu-list button, .menu-list a { min-height: var(--tap); }
  .foot-grid a:not(.brand) { padding: 12px 0; }
  .foot-grid h2 { margin-bottom: 4px; }
  .foot-brand .brand { padding-block: 9px; margin-block: -9px; }
  .crumbs { row-gap: 16px; }
  .crumbs a, .back, .foot-legal a { display: inline-block; padding: 12px 0; margin: -12px 0; }
  .essay-more a { padding: 12px 0; }
  .handle { position: relative; }
  .handle::after { content: ""; position: absolute; inset: -6px; }
}

/* The install invitation on phones (assets/pwa.js). */
.install-sheet { position: fixed; left: 12px; right: 12px; bottom: calc(12px + env(safe-area-inset-bottom)); z-index: var(--z-sheet); display: grid; grid-template-columns: 48px minmax(0, 1fr); gap: 10px 12px; align-items: center; padding: 14px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--shadow-lg); animation: rise .35s var(--ease); }
.install-sheet img { border-radius: 12px; }
.install-sheet p { color: var(--muted); font-size: 13.5px; margin-top: 2px; }
.install-acts { grid-column: 1 / -1; display: flex; justify-content: flex-end; gap: 8px; }
.install-share { display: inline-grid; place-items: center; vertical-align: -3px; }
.install-share svg { width: 16px; height: 16px; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* Share links: a link button beside page titles, and the item a shared link points to. */
.title-row { display: flex; align-items: center; gap: 2px; min-width: 0; }
.share-btn { color: var(--faint); flex: none; }
.share-btn:hover { color: var(--accent); }
.slot { scroll-margin-top: 90px; }
.slot.flash { animation: flash 2.8s var(--ease); }
@keyframes flash { 0%, 40% { background: var(--accent-soft); box-shadow: inset 3px 0 0 var(--accent); } }

/* The installed app (home screen or desktop window) scrolls without showing a scrollbar, like a
   native app. A normal browser tab keeps its scrollbar. */
@media (display-mode: standalone) {
  html, body, * { scrollbar-width: none; }
  html::-webkit-scrollbar, body::-webkit-scrollbar, *::-webkit-scrollbar { width: 0; height: 0; display: none; }
}

/* Page to page, the browser morphs instead of flashing (cross-document View Transitions: Chrome,
   Edge and Safari 18+, the installed app included; other browsers just change page). The nav stays
   put and the page content fades and rises. Off for people who ask for less motion. */
@view-transition { navigation: auto; }
.nav { view-transition-name: site-nav; }
main { view-transition-name: page; }
::view-transition-old(page) { animation: page-out .16s var(--ease) both; }
::view-transition-new(page) { animation: page-in .3s var(--ease) both; }
@keyframes page-out { to { opacity: 0; transform: translateY(-6px); } }
@keyframes page-in { from { opacity: 0; transform: translateY(10px); } }
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}
/* Adding: morph() in app.js moves one element to its new place in a same-document view transition.
   The rest of the page changes at once, without the page-to-page fade, and clicks reach the page. */
.morphing main { view-transition-name: none; }
.morphing::view-transition { pointer-events: none; }
.morphing::view-transition-old(root), .morphing::view-transition-new(root) { animation: none; }
::view-transition-group(morph) { animation-duration: .42s; animation-timing-function: var(--ease); }
/* A round button and a wide row differ in shape: each image keeps its own inside the moving box,
   and the old one gives way quickly, so the row grows out of what it came from. */
::view-transition-old(morph), ::view-transition-new(morph) { width: 100%; height: 100%; object-fit: contain; }
::view-transition-old(morph) { animation-duration: .12s; }
/* Deleting: trash() in app.js flies a copy of the row into a bin that pops up in the corner. */
.trash-ghost { position: fixed; z-index: var(--z-ghost); margin: 0; pointer-events: none; background: var(--surface); border-radius: var(--r); box-shadow: var(--shadow-lg); }
.trash-bin {
  position: fixed; z-index: var(--z-ghost); right: max(20px, env(safe-area-inset-right)); bottom: max(20px, env(safe-area-inset-bottom));
  width: 52px; height: 52px; border-radius: 50%; display: grid; place-items: center; pointer-events: none;
  color: var(--danger); background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow-lg);
}

/* Profile settings: each one opens like a drawer (a native details element, so keyboards and
   screen readers get it for free). */
details.setting > summary { list-style: none; display: flex; align-items: center; gap: 12px; padding: 16px 20px; min-height: var(--tap); cursor: pointer; border-radius: inherit; }
details.setting > summary::-webkit-details-marker { display: none; }
details.setting > summary .grow { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
details.setting > summary h2 { font-size: 16px; }
details.setting > summary::after { content: ""; flex: none; width: 9px; height: 9px; margin: -4px 4px 0 auto; border-right: 2px solid var(--faint); border-bottom: 2px solid var(--faint); transform: rotate(45deg); transition: transform var(--t) var(--ease); }
details.setting[open] > summary::after { transform: rotate(-135deg); margin-top: 5px; }
details.setting > summary:hover h2 { color: var(--accent); }
details.setting > .setting-body { padding: 16px 20px 20px; border-top: 1px solid var(--border); }
details.setting.danger-zone > summary h2 { color: var(--danger); }
.steps { margin: 10px 0 0; padding-left: 22px; }
.steps li { margin: 6px 0; }
.setting-row { padding: 12px 20px; min-height: calc(var(--tap) + 30px); }
.setting-row h2, .setting-plans h2 { font-size: 16px; }
/* The small picture at the left of each profile section says what it is about before you read. */
.setting-icon { flex: none; width: 36px; height: 36px; border-radius: 10px; display: grid; place-items: center; background: var(--accent-soft); color: var(--accent); }
.danger-zone .setting-icon { background: var(--danger-soft); color: var(--danger); }
.setting-head { display: flex; align-items: center; gap: 12px; }
/* API tokens in the profile: one row each, and the secret shown once with a copy button. */
.token-list { list-style: none; margin: 0 0 14px; padding: 0; }
.token-list li { display: flex; align-items: center; gap: 12px; padding: 10px 0; }
.token-list li + li { border-top: 1px solid var(--border); }
.token-list .grow { display: flex; flex-direction: column; gap: 2px; min-width: 0; overflow-wrap: anywhere; }
.token-secret { display: flex; gap: 8px; }
.token-secret input { flex: 1; min-width: 0; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 13px; }
/* Round icon buttons (new team, project, invite, settings, the topic toolbar) sit at the size of the text
   beside them. The invisible ring keeps the tap target near 44px, and toolbars holding them space out a
   little so neighbouring rings barely overlap. */
.btn-round { border-radius: 50%; width: 30px; height: 30px; min-width: 30px; min-height: 30px; padding: 0; }
.btn-round svg { width: 16px; height: 16px; }
.btn-round::before { content: ""; position: absolute; inset: -7px; border-radius: 50%; }
.toolbar:has(.btn-round) { gap: 14px; }
.logline .btn-round + .btn-round { margin-left: 4px; }
/* Project and topic heads: the text on the left, its settings and delete right beside it on every screen. */
.page-head.head-split { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.page-head.head-split > .head-row { flex: 1 1 auto; min-width: 0; }
.page-head.head-split > .head-row > div { min-width: 0; }
.page-head.head-split > .toolbar { flex: none; flex-wrap: nowrap; width: auto; }  /* the top right corner */
/* A topic's more options and add, on the left above the list. */
.topic-actions { display: flex; align-items: center; gap: 14px; margin: -6px 0 16px; }
.line-li .line-marker { margin: 4px 0; }
/* A field in the Fields drawer: its name, and its type underneath behind the same bar as an item's reason. */
.field-row { align-items: center; gap: 12px; padding: 14px 0; }
.field-text { flex: 1 1 0; min-width: 0; }
.field-name { font-weight: 640; font-size: 15px; letter-spacing: -.012em; overflow-wrap: anywhere; }
.field-row .slot-why { margin-top: 6px; }
/* "holds the pen" in the people list opens the pen dialog: a tag that presses, with a finger-sized target. */
.tag-btn { position: relative; border: 0; font-family: inherit; cursor: pointer; }
.tag-btn::before { content: ""; position: absolute; inset: -10px -4px; }
.tag-btn:hover { text-decoration: underline; }
.tag-btn:focus-visible { outline: none; box-shadow: var(--ring); }
/* A member's team head has no settings button; its empty toolbar takes no row. */
.page-head .toolbar:not(:has(*)) { display: none; }
/* Markdown: rendered reasons, descriptions and notes (markdown.js), and the editor that writes them. */
.md { overflow-wrap: anywhere; }
.md > * + * { margin-top: 6px; }
.md p { margin: 0; }
.md .md-h { font-weight: 650; color: var(--text); }
.md ul, .md ol { margin-block: 0; padding-left: 20px; }
.md li + li { margin-top: 2px; }
.md ul.md-tasks { list-style: none; padding-left: 0; }
.md .md-tasks li { display: flex; gap: 8px; align-items: baseline; }
.md .md-tasks input { margin: 0; accent-color: var(--accent); }
.md blockquote { margin: 0; padding-left: 10px; border-left: 2px solid var(--border-strong); color: var(--muted); }
.md code, .flag-note code, .log-text code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: .92em; padding: 1px 5px; border-radius: 5px; background: var(--surface-2); }
.md pre { margin: 0; padding: 10px 12px; border-radius: var(--r-sm); background: var(--surface-2); overflow-x: auto; }
.md pre code { padding: 0; background: none; }
.md a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
.flag-note a, .log-text a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.page-head .head-desc { margin-top: 6px; font-size: 14.5px; }  /* a project's or a topic's description */
.md-field .md-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
.md-field .md-head label { margin: 0; }
.md-tabs { display: inline-flex; gap: 2px; padding: 2px; border-radius: 9px; background: var(--surface-2); }
.md-tabs button { border: 0; background: none; font: inherit; font-size: 12.5px; font-weight: 600; color: var(--muted); padding: 4px 10px; border-radius: 7px; cursor: pointer; }
.md-tabs button[aria-pressed="true"] { background: var(--surface); color: var(--text); box-shadow: var(--shadow-sm); }
.md-tabs button:focus-visible { outline: none; box-shadow: var(--ring); }
.md-toolbar { display: grid; grid-template-columns: repeat(8, minmax(0, 40px)); gap: 2px; padding: 4px; border: 1px solid var(--border); border-bottom: 0; border-radius: var(--r-sm) var(--r-sm) 0 0; background: var(--surface-2); }
.md-toolbar button { position: relative; display: grid; place-items: center; width: 100%; height: 30px; border: 0; border-radius: 7px; background: none; color: var(--muted); cursor: pointer; }
.md-toolbar button:hover { background: var(--surface); color: var(--text); }
.md-toolbar button:focus-visible { outline: none; box-shadow: var(--ring); }
.md-field textarea { border-top-left-radius: 0; border-top-right-radius: 0; }
.md-preview { min-height: 96px; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--r-sm); background: var(--surface); color: var(--text); font-size: 14px; }
.md-preview:empty::before { content: "Nothing to preview yet."; color: var(--faint); }
.md-count { margin: 6px 0 0; font-size: 12.5px; color: var(--faint); text-align: right; }
.md-count:empty { display: none; }
@media (pointer: coarse) { .md-toolbar button { height: 38px; } }
.topic-actions .menu-list { right: auto; left: 0; }  /* it sits on the left, so it opens to the right */
/* A title with one action button: the button stays beside the title on every width. */
.head-action { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.head-action > div { min-width: 0; }
.head-action > .btn { flex: none; margin-top: 2px; }
/* The last tile of a grid adds one more: a dashed card around a round plus. */
.tile-add { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; width: 100%; min-height: 128px; border-style: dashed; border-color: var(--border-strong); background: none; font: inherit; font-size: 14px; font-weight: 600; color: var(--muted); cursor: pointer; }
.tile-add:hover { color: var(--accent); }
/* A project's or topic's picture: the pen holder taps it to change it. */
.logo-edit { position: relative; flex: none; display: grid; place-items: center; min-width: 44px; min-height: 44px; padding: 0; border: 0; background: none; border-radius: 12px; cursor: pointer; }
.history-nav { display: flex; align-items: center; justify-content: flex-end; gap: 10px; margin-top: 12px; }
.history-nav .faint { font-size: 12.5px; }

/* The admin page: rows of one big number each, a bar per day, and a review waiting to be read. */
.figures { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 12px; }
.figure { display: grid; gap: 2px; padding: 16px 18px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--r); }
.figure-value { font-size: 30px; font-weight: 800; letter-spacing: -.03em; line-height: 1.1; font-variant-numeric: tabular-nums; }
.figure-label { font-size: 13px; font-weight: 600; color: var(--text-2); }
.figure-note { font-size: 12px; color: var(--faint); }
.spark { display: flex; align-items: flex-end; gap: 3px; height: 54px; }
.spark-bar { flex: 1; min-height: 2px; height: var(--h, 2%); border-radius: 3px 3px 0 0; background: var(--accent); opacity: .85; }
.review-row { display: grid; gap: 10px; }
.queue-tabs { flex-wrap: wrap; margin-bottom: 12px; }
.account-search { margin-bottom: 12px; gap: 8px; }
.account-search input { flex: 1; min-width: 0; }
.account-facts { gap: 10px; flex-wrap: wrap; justify-content: flex-end; font-size: 12.5px; }
@media (max-width: 560px) { .account-facts { justify-content: flex-start; } }
.queue-tabs .on { color: var(--accent); border-color: var(--accent); }
.money-note { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.review-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.review-row blockquote { margin: 0; font-size: 15px; line-height: 1.6; color: var(--text-2); overflow-wrap: anywhere; }
.review-row .review-stars { color: #f0a500; letter-spacing: 2px; }
.btn.danger, .btn-ghost.danger { color: var(--danger); }

/* Stars: the ones you pick in your profile, and the ones a review shows. */
.stars { display: flex; gap: 4px; }
.star { padding: 4px; border: 0; background: none; cursor: pointer; color: var(--border-strong); line-height: 0; border-radius: var(--r-sm); }
.star[aria-pressed="true"] { color: #f0a500; }
.star svg { fill: currentColor; }
.star:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.label-line { display: block; font-size: 13.5px; font-weight: 600; margin-bottom: 7px; }

/* A count riding on the corner of a button: the teams already paid for, on New team. */
.with-bubble { position: relative; display: inline-flex; }
.bubble { position: absolute; top: -5px; right: -5px; min-width: 19px; height: 19px; padding: 0 5px; border-radius: 20px; display: grid; place-items: center; font-size: 11px; font-weight: 700; background: var(--money); color: var(--bg); border: 2px solid var(--bg); box-shadow: var(--shadow-sm); pointer-events: none; }
/* A description on a tile: the shape it was written in, cut off after a few lines. */
.tile-desc { max-height: 5.4em; overflow: hidden; margin-top: 4px; -webkit-mask-image: linear-gradient(#000 70%, transparent); mask-image: linear-gradient(#000 70%, transparent); }
.md-box { flex: none; width: 11px; height: 11px; border-radius: 3px; border: 1.5px solid var(--border-strong); }
.md-box.on { background: var(--accent); border-color: var(--accent); }
.logo-badge { position: absolute; right: -4px; bottom: -4px; width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; background: var(--surface); color: var(--text); border: 1px solid var(--border); box-shadow: var(--shadow-sm); }
.logo-edit:hover .logo-badge { color: var(--accent); }
/* Project and topic tiles: the picture large on the left, the details beside it. */
.tile-media { display: flex; gap: 14px; align-items: flex-start; }
.tile-main { flex: 1; min-width: 0; }
.tile-main > p.faint { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.tile-pic { flex: none; width: 64px; height: 64px; border-radius: 14px; object-fit: cover; display: grid; place-items: center; font-size: 20px; font-weight: 750; letter-spacing: -.02em; }
span.tile-pic { background: var(--accent-soft); color: var(--accent); }
/* What is under a project: its topics' pictures, overlapped like faces, with the numbers beside them.
   The tile is narrow, so the pictures never shrink and the count wraps under them instead. */
.strip { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; margin-top: 12px; }
.strip .faint { font-size: 12.5px; }
.pic-stack { flex: none; display: flex; }  /* .stack is taken: it stacks things downward */
.pic-stack > * { margin-left: -7px; }
.pic-stack > *:first-child { margin-left: 0; }
.pic-sm { flex: none; width: 26px; height: 26px; border-radius: 8px; object-fit: cover; display: grid; place-items: center; font-size: 10px; font-weight: 750; border: 2px solid var(--surface); }
span.pic-sm { background: var(--accent-soft); color: var(--accent); }
.push-bell { width: 48px; height: 48px; border-radius: 12px; display: grid; place-items: center; background: var(--grad-fill); color: #fff; }

/* API docs page (web/src/pages/api-docs.html, built by docs_gen). */
.docs { display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: 40px; max-width: 1120px; margin: 0 auto; padding: 24px 24px 80px; }
.docs-nav { position: sticky; top: 76px; align-self: start; max-height: calc(100vh - 96px); overflow-y: auto; padding-right: 8px; padding-bottom: 16px; font-size: 13.5px; }
.docs-nav-title { margin: 18px 0 6px; font-size: 11px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--faint); }
.docs-nav-title:first-child { margin-top: 0; }
.docs-nav a { display: block; padding: 5px 10px; border-left: 2px solid var(--border); color: var(--muted); text-decoration: none; }
.docs-nav a:hover { color: var(--text); }
.docs-nav a.active { color: var(--accent); border-left-color: var(--accent); font-weight: 600; }
.docs-main { min-width: 0; max-width: 820px; }
.docs-hero { padding: 12px 0 8px; }
.docs-eyebrow { display: inline-block; margin: 0 0 12px; padding: 4px 12px; border-radius: 999px; font-size: 12.5px; font-weight: 600; color: var(--accent); background: var(--accent-soft); }
.docs-hero h1 { font-size: clamp(28px, 4vw, 40px); line-height: 1.1; letter-spacing: -.02em; }
.docs-lead { margin: 12px 0 18px; font-size: 16.5px; color: var(--muted); max-width: 640px; }
.docs-actions { display: flex; flex-wrap: wrap; gap: 10px; }
.docs-main h2 { margin: 48px 0 12px; font-size: 24px; letter-spacing: -.01em; scroll-margin-top: 80px; }
.docs-main h3 { margin: 28px 0 8px; font-size: 17px; scroll-margin-top: 80px; }
.docs-main p, .docs-main li { color: var(--text-2); line-height: 1.65; }
.docs-main ol { padding-left: 22px; }
.docs-main :not(pre) > code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: .88em; padding: 1px 6px; border-radius: 6px; background: var(--surface-2); border: 1px solid var(--border); overflow-wrap: anywhere; }
.docs-note { margin: 14px 0; padding: 12px 16px; border-radius: var(--r-sm); border-left: 3px solid var(--accent); background: var(--accent-soft); color: var(--text-2); font-size: 14.5px; }
.docs-ep { margin: 26px 0 34px; scroll-margin-top: 80px; }
.docs-ep h3 { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 0 0 4px; font-size: 15px; }
.docs-ep h3 code { font-size: 14px; background: none !important; border: 0 !important; padding: 0 !important; }
.docs-ep-title { margin: 0 0 4px; font-weight: 650; color: var(--text) !important; }
.docs-m { display: inline-block; padding: 2px 8px; border-radius: 6px; font-size: 11.5px; font-weight: 800; letter-spacing: .04em; }
.docs-m-get { color: var(--money); background: var(--money-soft); border: 1px solid color-mix(in srgb, var(--money) 35%, transparent); }
.docs-m-post { color: var(--accent); background: var(--accent-soft); border: 1px solid var(--accent-line); }
.docs-who { margin-left: auto; font-size: 12px; font-weight: 600; color: var(--faint); }
/* Code blocks stay dark in both themes, so their text colours are fixed rather than theme tokens. */
.docs-code { margin: 10px 0; border-radius: var(--r-sm); background: #11141c; border: 1px solid #1f2533; overflow: hidden; }
.docs-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; padding: 6px 8px 6px 12px; background: #090b11; border-bottom: 1px solid #1f2533; }
.docs-bar-label { margin-right: 8px; font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: #8b93a7; }
.docs-tab { border: 0; background: none; font: inherit; font-size: 12.5px; color: #8b93a7; padding: 4px 9px; border-radius: 6px; cursor: pointer; }
.docs-tab[aria-pressed="true"] { color: #fff; background: #1f2533; }
.docs-copy { margin-left: auto; border: 1px solid #2a3142; background: none; color: #b7bfd0; font: inherit; font-size: 12px; padding: 4px 10px; border-radius: 6px; cursor: pointer; }
.docs-copy:hover { color: #fff; border-color: #3a4358; }
.docs-status { font-size: 12px; font-weight: 700; padding: 2px 8px; border-radius: 6px; }
.docs-status-ok { color: #6ee7b7; background: rgba(16, 185, 129, .14); }
.docs-status-err { color: #fca5a5; background: rgba(239, 68, 68, .14); }
.docs-code pre { margin: 0; padding: 14px 16px; overflow-x: auto; max-height: 420px; }
.docs-code pre code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 13px; line-height: 1.6; color: #d6dbe6; white-space: pre; }
.docs-tab:focus-visible, .docs-copy:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.docs-table { overflow-x: auto; margin: 12px 0; border: 1px solid var(--border); border-radius: var(--r-sm); }
.docs-table table { width: 100%; border-collapse: collapse; font-size: 14px; }
.docs-table th, .docs-table td { padding: 9px 12px; text-align: left; border-bottom: 1px solid var(--border); vertical-align: top; }
.docs-table th { font-size: 12px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); background: var(--surface-2); }
.docs-table tr:last-child td { border-bottom: 0; }
/* Slot counters ("3 of 10") beside a section title, from capCount in app.js. */
/* A template's card on a team that has nothing yet. */
.template-card { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.template-card .hint { margin: 0; }
.template-card .btn { margin-top: 6px; }
.cap-count { font-size: 12.5px; font-weight: 650; color: var(--faint); font-variant-numeric: tabular-nums; white-space: nowrap; padding: 2px 8px; border-radius: 999px; background: var(--surface-2); border: 1px solid var(--border); }
.cap-count.full { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 40%, var(--border)); }
.page-head .title-row .cap-count { align-self: center; }
/* The accounts menu under the face in the app header (app.js, accountMenu). */
.nav-account > summary.nav-me { cursor: pointer; }
.nav-account > summary.nav-me:focus-visible { outline: none; box-shadow: var(--ring); }
.account-menu { width: min(300px, calc(100vw - 32px)); }
.account-menu .account-now, .account-menu [data-slot] { display: flex; align-items: center; gap: 10px; }
.account-menu .account-now { padding: 8px 12px 10px; }
.account-menu strong { display: block; font-size: 14px; line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.account-menu .grow .faint { display: block; font-size: 12.5px; line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.account-menu .account-label { padding: 6px 12px 2px; font-size: 11.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; }
.account-menu .avatar { flex: none; }
/* However many accounts a browser holds, the menu stays a menu: the switch list scrolls inside it. */
.account-list { max-height: 244px; overflow-y: auto; overscroll-behavior: contain; }
.account-list::-webkit-scrollbar { width: 10px; }
.account-list::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 10px; border: 3px solid var(--surface); }
/* Appearance on the profile: the chosen one reads as pressed. */
.theme-choice .btn[aria-pressed="true"] { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
@media (max-width: 960px) {
  .docs { grid-template-columns: minmax(0, 1fr); gap: 16px; padding: 16px 16px 64px; }
  .docs-nav { position: static; max-height: none; display: flex; flex-wrap: wrap; gap: 4px 6px; padding: 0 0 12px; border-bottom: 1px solid var(--border); }
  .docs-nav-title { display: none; }
  .docs-nav a { border: 1px solid var(--border); border-radius: 999px; padding: 4px 10px; font-size: 12.5px; }
  .docs-who { margin-left: 0; width: 100%; }
}
