/* ui.css: the one kit (ADR 0023 decisions 3, 5, 7, 11). Every host links it first: the Hologram
   layout (board, home, changelog), a Space, /me, the docs page and the error page. Host sheets keep
   layout; a look that crosses surfaces lives here.

   Type, a scale and not a variable per size: 11 12 13 (chrome) 14 (lists, menus) 15 (plain pages,
   panels) 16 (notes; fields on a coarse pointer) 20 (sheet titles) 32 (page titles); weights 400,
   500, 600. Spacing: 2 4 6 8 10 12 16 20 24 32 48. A modal is --bg with --shadow-lg; anything
   floating is --panel with --shadow.

   Every colour is a light-dark() pair, light first (report 10 section 4.1). color-scheme picks the
   half, and it follows the system; a choice kept in this browser is one adopted line from scheme.js
   (ADR 0023 C11). A light island is one declaration, color-scheme: light. The rule for dark
   (decision 11): a colour a person chose stays, what 1charta draws on its own ground follows the
   theme, documents stay light. test/runtime/contrast.test.mjs checks every pair both ways and that
   the fallback below is exactly the light halves. */

@font-face { font-family: "Inter"; font-style: normal; font-weight: 100 900; font-display: swap; src: url("/fonts/inter-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 {
  color-scheme: light dark;
  --font: Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, monospace;
  --ink: light-dark(#1f2937, #e8e6e1);
  --ink-strong: light-dark(#111827, #faf9f7);
  --muted: light-dark(#5f6672, #aaa69c);
  --faint: light-dark(#9ca3af, #6b675f);
  --bg: light-dark(#f6f5f1, #1b1a18);
  --panel: light-dark(#ffffff, #252421);
  --line: light-dark(#e5e3dd, #3a3834);
  --edge: light-dark(#8f8b80, #7d796f);
  --hover: light-dark(#ecebe6, #302f2b);
  --pressed: light-dark(#e6e4dd, #3a3935);
  --accent: light-dark(#2563eb, #6ea2ff);
  --accent-strong: light-dark(#1d4ed8, #9cc0ff);
  --accent-soft: light-dark(#e8effd, #1f2b44);
  --danger: light-dark(#b91c1c, #f87171);
  --danger-strong: light-dark(#7f1d1d, #fca5a5);
  --danger-soft: light-dark(#fef2f2, #3b1f1f);
  --amber-soft: light-dark(#fffbeb, #342a12);
  --amber-line: light-dark(#fcd34d, #8a6a17);
  --amber-ink: light-dark(#92400e, #e2b05c);
  --green-ink: light-dark(#166534, #86efac);
  --green-soft: light-dark(#e7f4ea, #17301f);
  --peer: light-dark(#7c3aed, #a78bfa);
  --dot: light-dark(#c9c6bd, #46433d);
  --on-ink: light-dark(#ffffff, #1b1a18);
  --on-accent: light-dark(#ffffff, #0b1426);
  --mark: light-dark(#fff3a0, #4a3b0b);
  --mark-strong: light-dark(#fbbf24, #6e5207);
  --placeholder: light-dark(#736e66, #938e85);
  --backdrop: light-dark(rgba(15, 23, 42, .32), rgba(0, 0, 0, .55));
  --scroll-shade: light-dark(rgba(0, 0, 0, .14), rgba(0, 0, 0, .6));
  --shadow: 0 0 0 1px light-dark(#0000, #ffffff14), 0 1px 2px light-dark(#0000000d, #00000066), 0 8px 24px light-dark(#0000001a, #00000080);
  --shadow-lg: 0 0 0 1px light-dark(#0000, #ffffff14), 0 24px 64px light-dark(rgba(0, 0, 0, .2), rgba(0, 0, 0, .6));
  --r-xs: 4px; --r-sm: 6px; --r: 8px; --r-md: 10px; --r-lg: 12px;
  --fast: 120ms; --slow: 200ms; --ease: cubic-bezier(.2, .7, .2, 1);
  /* the one opacity of a control that cannot be pressed (decision 5) */
  --disabled: .5;
}

/* Below Chrome 123, Safari 17.5 and Firefox 120 a pair is invalid where it is used and the page
   would draw unstyled: those browsers get the light halves, and stay light. */
@supports not (color: light-dark(#fff, #000)) {
  :root {
    --ink: #1f2937;
    --ink-strong: #111827;
    --muted: #5f6672;
    --faint: #9ca3af;
    --bg: #f6f5f1;
    --panel: #ffffff;
    --line: #e5e3dd;
    --edge: #8f8b80;
    --hover: #ecebe6;
    --pressed: #e6e4dd;
    --accent: #2563eb;
    --accent-strong: #1d4ed8;
    --accent-soft: #e8effd;
    --danger: #b91c1c;
    --danger-strong: #7f1d1d;
    --danger-soft: #fef2f2;
    --amber-soft: #fffbeb;
    --amber-line: #fcd34d;
    --amber-ink: #92400e;
    --green-ink: #166534;
    --green-soft: #e7f4ea;
    --peer: #7c3aed;
    --dot: #c9c6bd;
    --on-ink: #ffffff;
    --on-accent: #ffffff;
    --mark: #fff3a0;
    --mark-strong: #fbbf24;
    --placeholder: #736e66;
    --backdrop: rgba(15, 23, 42, .32);
    --scroll-shade: rgba(0, 0, 0, .14);
    --shadow: 0 0 0 1px #0000, 0 1px 2px #0000000d, 0 8px 24px #0000001a;
    --shadow-lg: 0 0 0 1px #0000, 0 24px 64px rgba(0, 0, 0, .2);
  }
}

/* hosts keep their own sizes */
html, body { font-family: var(--font); color: var(--ink); background: var(--bg); }
[hidden] { display: none !important; }

/* Keyboard focus is seen on everything that takes it; a pointer click does not ring what it lands
   on. A list, not one :is(): [tabindex] inside :is() would lift every element to its weight and
   ring fields a host means to leave bare (the switcher). A tree row keeps its inset offset. */
:is(a, button, summary, input, select, textarea):focus-visible, [tabindex]:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
:is(a, button, summary, input, select, textarea):focus:not(:focus-visible) { outline: none; }

/* Asked for less motion: nothing slides, fades or pulses; camera flights are board.js's. Zero, not
   the usual .01ms: transition-property is `all` by default, so .01ms on every element would make
   every change a transition, and anything measured in the same frame reads the old value (an SVG
   rect's width, as the marquee found). No script here waits for a transitionend. */
@media (prefers-reduced-motion: reduce) {
  *, ::before, ::after { animation-duration: 0s !important; animation-delay: 0s !important; animation-iteration-count: 1 !important; transition-duration: 0s !important; transition-delay: 0s !important; }
}

/* Forced colours (Windows contrast themes): the switch is a checkbox again, a selected or current
   row keeps a mark that is not a fill, and a colour someone chose stays that colour. */
@media (forced-colors: active) {
  .sw input { appearance: auto; }
  :is([aria-selected=true], [aria-current]) { outline: 2px solid Highlight; }
  :is(.swatch, .sw, .person i, .avatar, .faces .av) { forced-color-adjust: none; }
}

/* --- THE KIT (ADR 0023 decision 4; the plan's C3) ------------------------------------------------
   The look of every class that crosses surfaces, once. This file loads first, so a host rule of the
   same weight wins: a host keeps layout, and a look a host still writes is a copy to delete, never a
   reason to add weight here. */

/* A button is the secondary one unless it says otherwise. No height: a host sizes its own widgets
   (a table's handles, a gutter's "+"), and a min-height here would override every one of them;
   targets are decision 7's, per control. */
button { padding: 6px 12px; border: 1px solid var(--line); border-radius: var(--r); background: var(--panel);
  color: inherit; font: inherit; font-size: 13px; font-weight: 500; cursor: pointer; }
/* one class weight: a host that dresses its own button with one class keeps its own hover */
@media (hover: hover) { :where(button):hover { background: var(--hover); } }
/* The one thing to do. Ink, because blue means selection, focus and links only. 32 px tall, 44 on
   a finger: this, a danger text button and a sheet's answers are the text buttons that get a height
   (a menu's rows and a widget's buttons are sized by their host). */
:is(button, a).primary { border-color: var(--ink); background: var(--ink); color: var(--on-ink); min-height: 32px; }
/* flex, so the words sit in the middle of the height */
a.primary { display: inline-flex; align-items: center; justify-content: center; padding: 6px 12px; border: 1px solid var(--ink);
  border-radius: var(--r); font-size: 13px; font-weight: 500; text-decoration: none; }
@media (hover: hover) { :is(button, a).primary:hover { background: var(--ink-strong); } }
.danger { color: var(--danger); }
:is(button.danger:not([role=menuitem]), :is(dialog.sheet, dialog.check-sheet) .row button) { min-height: 32px; }
@media (pointer: coarse) { :is(:is(button, a).primary, button.danger:not([role=menuitem]), :is(dialog.sheet, dialog.check-sheet) .row button) { min-height: 44px; } }
/* a button that reads as a link in its sentence: the line keeps its height, a finger still gets 44px */
button.quiet { padding: 0; border: 0; background: none; color: inherit; font: inherit; text-decoration: underline; }
@media (pointer: coarse) { button.quiet { padding: 13px 0; margin: -13px 0; } }
/* the one close: a glyph with a 24px target, named "Close" where it is made */
button.close { min-width: 24px; min-height: 24px; padding: 0 4px; border: 0; background: none; color: var(--muted); font: inherit; font-size: 16px;
  font-weight: 400; line-height: 1; }
@media (hover: hover) { button.close:hover { background: none; color: var(--ink); } }
@media (pointer: coarse) { button.close { min-width: 44px; min-height: 44px; } }
/* at work (decision 5): the button says its -ing word; the look adds nothing that takes room. A button that
   names that word in `data-busy` lays it out from the start, flat and unseen under its label, so it is as
   wide as the wider of the two and nothing beside it moves when it is pressed (verify-4). Never a quiet one:
   a link in a sentence that reserved room left a hole beside its words at rest (verify-5); pressed, it grows once */
[aria-busy=true] { cursor: progress; }
button[data-busy]:not(.quiet)::before { content: attr(data-busy); display: block; height: 0; overflow: hidden; visibility: hidden; }
/* "Copy" that turns into "Copied": as wide as the longer word from the start, and the field beside it stays put */
button.copy { min-width: 5.6em; }
:where(button)[aria-busy=true] { color: var(--muted); }
/* the button a menu hangs from, while the menu is open: its fill and a ring, since on a lit row the fill
   alone is one step from the row's (--pressed on --hover is 1.05:1). One look on home, in a Space and on a
   board, so this one weighs: the attribute is doubled to beat a host's button and its :hover (0,3,0 at most) */
button[aria-haspopup=menu][aria-haspopup=menu][aria-expanded=true] { background: var(--pressed); box-shadow: inset 0 0 0 1px var(--muted); }
/* what cannot be pressed right now (a control: a list row that only says something is not one) */
:where(button, a, input, select, textarea, [role=button], [role=menuitem]):is(:disabled, [aria-disabled=true]) { opacity: var(--disabled); cursor: default; }

/* Fields, never the browser's own box. No weight at all: any host rule that names a field, even
   a bare `input`, wins, so a field a host draws on purpose (a title, the canvas editor) stays its. */
:where(input:not([type=checkbox], [type=radio], [type=range], [type=file], [type=color], [type=hidden], [type=button], [type=submit]), select, textarea) {
  padding: 8px 10px; border: 1px solid var(--edge); border-radius: var(--r); background: var(--panel); color: inherit;
  font: inherit; font-size: 14px; }
/* 16px: under that, iOS zooms the page into a field */
@media (pointer: coarse) { :where(input:not([type=checkbox], [type=radio], [type=range], [type=file], [type=color], [type=hidden], [type=button], [type=submit]), select, textarea) { font-size: 16px; } }
/* what a field asks for, quieter than what is typed and still read (4.5:1 on a panel and on the ground) */
::placeholder { color: var(--placeholder); opacity: 1; }
/* a menu of options is a field too: the kit's chevron, drawn in the text's own colour, never Safari's bevel */
:where(select) { appearance: none; padding-right: 28px;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 15px) 50%, calc(100% - 10px) 50%; background-size: 5px 5px; background-repeat: no-repeat; }
:where(input[type=checkbox], input[type=radio]) { accent-color: var(--ink); }

/* A choice of a few: pills in a row, ink when chosen. Radios, so the arrows walk them and a screen
   reader reads the legend first. */
fieldset.seg { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 0; padding: 0; border: 0; }
fieldset.seg legend { padding: 0; color: var(--muted); font-size: 13px; }
fieldset.seg input { position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; }
fieldset.seg label { flex: none; padding: 5px 12px; border: 1px solid var(--line); border-radius: 999px; background: var(--panel);
  color: var(--muted); font-size: 13px; cursor: pointer; }
fieldset.seg label:hover { background: var(--hover); color: var(--ink); }
fieldset.seg input:checked + label { border-color: var(--ink); background: var(--ink); color: var(--on-ink); }
fieldset.seg input:focus-visible + label { outline: 2px solid var(--accent); outline-offset: 2px; }
/* A switch: a checkbox drawn as one. Off is a hollow track whose ring and knob are the field edge, so it
   is seen (3:1) and plainly off; on is filled ink with a knob of the panel. The ring is a shadow, not a
   border, so the knob sits where it did. */
.sw { display: flex; align-items: center; gap: 8px; }
.sw input { width: 34px; height: 20px; margin: 0; flex: none; appearance: none; border: 0; border-radius: 999px;
  background: var(--panel); box-shadow: inset 0 0 0 1px var(--edge); cursor: pointer; transition: background var(--fast); }
.sw input::after { content: ""; display: block; width: 16px; height: 16px; margin: 2px; border-radius: 50%;
  background: var(--edge); transition: transform var(--fast); }
.sw input:checked { background: var(--ink); box-shadow: none; }
.sw input:checked::after { transform: translateX(14px); background: var(--panel); }
.sw label { font-size: 14px; cursor: pointer; }
.sw i { color: var(--muted); font-style: normal; font-size: 12px; }
@media (pointer: coarse) {
  :is(fieldset.seg label, .sw label) { min-height: 44px; }
  fieldset.seg label { display: inline-flex; align-items: center; }
  .sw input { width: 44px; height: 26px; }
  .sw input::after { width: 22px; height: 22px; }
  .sw input:checked::after { transform: translateX(18px); }
}

/* A state in a word or two, in four tones. */
.pill { padding: 1px 8px; border-radius: 999px; background: var(--hover); color: var(--ink); font-size: 11px; font-weight: 600;
  white-space: nowrap; }
.pill.amber { background: var(--amber-soft); color: var(--amber-ink); box-shadow: inset 0 0 0 1px var(--amber-line); }
.pill.green { background: var(--green-soft); color: var(--green-ink); }
.pill.accent { background: var(--accent-soft); color: var(--accent-strong); }

/* A state that lasts: amber, wrapping, never cut off, the same on a board and in a Space: its words, then
   its one button at the end of the line (under them when they fill it). An answer to a press is a toast.
   Good news that goes by itself ("Back online.") is the calm tone. */
.notice { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; padding: 10px 14px; border: 1px solid var(--amber-line);
  border-radius: var(--r); background: var(--amber-soft); color: var(--amber-ink); font-size: 14px; line-height: 1.4;
  white-space: normal; overflow-wrap: anywhere; }
.notice > button { flex: none; margin-left: auto; }
.notice.ok { border-color: color-mix(in srgb, var(--green-ink) 30%, transparent); background: var(--green-soft); color: var(--green-ink); }

/* An answer to a press: the lane at the foot of the page (where it sits is the host's). The lane is a
   manual popover, lifted over a modal when an answer comes while one is open: the browser's popover
   box (centred, bordered, padded, painted) is taken back, as the tooltip's is. */
.toasts { display: flex; flex-direction: column; gap: 8px; pointer-events: none; inset: auto; margin: 0; padding: 0; border: 0;
  background: none; overflow: visible; }
:where(.toasts) > .toast { display: flex; gap: 10px; align-items: flex-start; max-width: min(520px, calc(100vw - 24px));
  padding: 10px 14px; border-radius: var(--r-md); background: var(--ink); color: var(--on-ink); font-size: 13px;
  box-shadow: var(--shadow); animation: rise var(--slow) var(--ease); }
:where(.toasts) > .toast.error { background: var(--danger-strong); color: var(--on-ink); }
:where(.toasts) .toast .act { min-height: 24px; padding: 0 2px; border: 0; background: none; color: var(--on-ink); font: inherit;
  font-weight: 500; text-decoration: underline; text-underline-offset: 2px; pointer-events: auto; }
:where(.toasts) .toast .close { color: var(--on-ink); pointer-events: auto; }
/* the buttons keep their 24 px (44 on a finger) without making the toast taller than its line: an error toast
   is as tall as any other, and its × and Undo sit on the words' line (verify-2) */
:where(.toasts) .toast :is(.act, .close) { margin-block: -3px; }
:where(.toasts) .toast .close { margin-right: -6px; }
@media (pointer: coarse) { :where(.toasts) .toast .close { margin-block: -13px; } }
@keyframes rise { from { transform: translateY(10px); opacity: 0; } to { transform: none; opacity: 1; } }

/* The one menu (menu.mjs): a native popover, its rows, its keys as muted text. */
.popmenu { position: fixed; inset: auto; margin: 0; min-width: 220px; max-width: 320px; max-height: calc(100dvh - 16px);
  overflow-y: auto; padding: 6px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--panel);
  box-shadow: var(--shadow); font-size: 14px; }
.popmenu [role=menuitem] { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; width: 100%;
  padding: 7px 10px; border: 0; border-radius: var(--r-sm); background: none; color: var(--ink); font: inherit;
  line-height: 20px; text-align: left; cursor: pointer; }
.popmenu [role=menuitem]:hover, .popmenu [role=menuitem]:focus-visible { background: var(--hover); outline: none; }
/* the item the keys are on is outlined, a greyed one too: the background alone is too faint to see */
.popmenu [role=menuitem]:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; opacity: 1; }
.popmenu [role=menuitem][aria-disabled=true]:hover { background: none; }
.popmenu [role=menuitem].danger { color: var(--danger); }
.popmenu [role=separator] { height: 1px; margin: 5px 4px; background: var(--line); }
.popmenu .cap { padding: 4px 10px; color: var(--muted); font-size: 11px; }

/* A heading of the page breaks where its lines come out even, never leaving one word on a line of its own; a
   note's headings are the note's, and break as Obsidian and the editor break them */
:is(h1, h2, h3, h4):not(.markdown-rendered *, .md *) { text-wrap: balance; }

/* A dialog is never the browser's own box, which in dark is a near-black darker than the page. */
dialog { background: var(--bg); color: var(--ink); }
/* Every modal: the ground of the page, raised, over one backdrop. (share.mjs names its check sheet
   alone, to keep it out of space.css's full-screen phone sheet; it is one of these all the same.) */
:is(dialog.sheet, dialog.check-sheet) { padding: 24px 28px; border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--bg);
  color: var(--ink); font-size: 15px; line-height: 1.5; box-shadow: var(--shadow-lg); }
dialog::backdrop { background: var(--backdrop); }
:is(dialog.sheet, dialog.check-sheet) h2:first-of-type { margin: 0 0 8px; color: var(--ink); font-size: 20px; font-weight: 600; }
/* a sheet's sentences end on more than one word (the picture sheet at 390, verify-2) */
:is(dialog.sheet, dialog.check-sheet) p { text-wrap: pretty; }

/* a key in a sentence is a cap; a key in a menu, a list or on a button is muted text */
kbd { padding: 0 4px; border: 1px solid var(--line); border-bottom-width: 2px; border-radius: var(--r-xs); background: var(--panel);
  font: inherit; font-size: 11px; }
:is(li, button, [role=option], [role=menuitem]) kbd { padding: 0; border: 0; background: none; color: var(--muted); font: 11px var(--font); }

/* A selected option and the current row keep a mark that is not only a fill (decision 7): a bar inside
   the left edge, straight whatever radius the row has (an inset shadow bent into a "(" on a round one). */
:is([role=option][aria-selected=true], .tree [aria-current=page]) { position: relative; }
:is([role=option][aria-selected=true], .tree [aria-current=page])::before { content: ""; position: absolute; left: 0; top: 6px; bottom: 6px;
  width: 2px; border-radius: 1px; background: var(--accent); }

/* The one "?" (help.mjs, C10): every key and action of the screen. The title and the field stay put, the
   list scrolls between them and the foot, and the foot is the theme switch, always in view. The same sheet
   on every surface; full screen on a phone. Its top is pinned, not centred: filtering shrinks the list, and a
   centred sheet would move the field under the caret (263 px at 1280, verify-4). */
dialog.sheet:has(> .help) { width: min(640px, 94vw); max-height: 80vh; margin-top: 7vh; margin-bottom: auto; overflow: hidden; }
dialog.sheet:has(> .help)[open] { display: flex; flex-direction: column; }
dialog.sheet:has(> .help) > .close { position: absolute; top: 22px; right: 20px; }
@media (max-width: 799px) { dialog.sheet:has(> .help) { width: 100vw; max-width: 100vw; height: 100dvh; max-height: 100dvh; margin: 0; padding: 16px;
  border: 0; border-radius: 0; } dialog.sheet:has(> .help) > .close { top: 14px; right: 12px; }
  /* one shape for every row on a narrow sheet: the name and its key on the first line, what it does under them */
  dialog.sheet .help li i { order: 1; flex-basis: 100%; } }
dialog.sheet > .help { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
dialog.sheet .help > input { flex: none; box-sizing: border-box; width: 100%; margin: 0 0 6px; padding: 9px 12px; }
dialog.sheet .help ul { flex: 1 1 auto; min-height: 0; overflow-y: auto; margin: 0; padding: 0; list-style: none; }
/* The list says there is more of it (verify-4 UX 7): a shade at the foot while rows lie below, at the top while
   rows lie above. Two covers of the ground scroll with the rows and hide each shade at its own end, so a list
   that fits shows none; a row cut at the foot reads as more under the shade, never as the end. */
dialog.sheet .help ul { background:
  linear-gradient(var(--bg) 40%, transparent) top / 100% 28px no-repeat local,
  linear-gradient(transparent, var(--bg) 60%) bottom / 100% 28px no-repeat local,
  radial-gradient(farthest-side at 50% 0, var(--scroll-shade), transparent) top / 100% 12px no-repeat scroll,
  radial-gradient(farthest-side at 50% 100%, var(--scroll-shade), transparent) bottom / 100% 12px no-repeat scroll; }
dialog.sheet .help li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 12px; padding: 7px 8px; border-radius: var(--r); font-size: 14px; }
dialog.sheet .help li[role=option]:not([aria-disabled]) { cursor: pointer; }
dialog.sheet .help li[aria-selected=true] { background: var(--hover); }
dialog.sheet .help li .label { flex: 0 1 auto; min-width: 0; }
dialog.sheet .help li i { flex: 1 1 14em; min-width: 0; color: var(--muted); font-size: 12px; font-style: normal; }
dialog.sheet .help li kbd { flex: none; margin-left: auto; white-space: nowrap; }
dialog.sheet .help li.cap { display: block; padding: 14px 8px 2px; color: var(--muted); font-size: 11px; font-weight: 600; }
dialog.sheet .help li.none { color: var(--muted); }
/* a shadow for the rule, not a border: a fieldset's border is where its legend sits */
dialog.sheet .help .scheme { flex: none; margin-top: 8px; padding-top: 12px; box-shadow: 0 -1px 0 var(--line); }
dialog.sheet .help .scheme legend { margin-bottom: 8px; }

/* One header row for the plain pages: the lockup left, the name or Your list and "?" right. */
.top { display: flex; align-items: center; justify-content: space-between; font-size: 13px; }
.top a { color: var(--muted); text-decoration: none; }
/* the lockup and the way back reach 24px under a mouse; home's own padded links (.new) keep theirs */
.top :where(.logo, .end a) { padding-block: 3px; margin-block: -3px; }
.top a:hover { color: var(--ink); }
.top .logo { display: inline-flex; align-items: center; gap: 8px; color: var(--ink); font-weight: 600; }
.top .end { display: flex; align-items: center; gap: 8px; }
/* the one "?" of a plain page, a ghost beside the way back to the list */
.top button.help { padding: 4px 9px; border: 0; background: none; color: var(--muted); font-size: 15px; font-weight: 600; }
@media (hover: hover) { .top button.help:hover { background: var(--hover); color: var(--ink); } }
@media (pointer: coarse) { .top button.help { min-width: 44px; min-height: 44px; } }
/* the header's links, which a thumb has to hit as much as any button */
@media (pointer: coarse) { .top a { padding-block: 13px; margin-block: -13px; } }

/* The lockup (docs/logo.md), on every page with room for it. The sticky is a picture, so its colours
   are literals: the one stays dark on the pink in either scheme. The script is page ink, so it is
   the logo drawn as a mask over var(--ink), cropped as the <img> it replaced was (the SVG is 4.81em
   wide at 1em tall; the first 0.69em, its own one, is cut off: the sticky is the one). */
.logo-mark { display: inline-flex; align-items: flex-end; font-size: 51px; line-height: 1; }
.logo-mark.sm { font-size: 23px; }
.logo-mark .script { display: block; height: 1em; width: 4.12em; background: var(--ink);
  mask: url(/images/charta-logo.svg) -0.69em 0 / auto 1em no-repeat; }
/* forced colours would repaint the ground under the mask as the page's own, and the script would go */
@media (forced-colors: active) { .logo-mark .script { forced-color-adjust: none; background: CanvasText; } }
/* The sticky, in golden ratio steps of the note (1em = the note, phi = 1.618):
   the note is the script x-height (420 of 680 units) times phi, so exactly the logo height, standing on the baseline;
   the one 1/phi^1.5 of the note tall, the fold 1/phi^3, the strip 1/phi^4, the gap 1/phi^5, the corners 1/phi^6. */
.app-one { box-sizing: border-box; position: relative; display: grid; place-items: center; font-size: 1em; font-style: normal;
  width: 1em; height: 1em; border-radius: 0.056em; margin: 0 0.09em 0.047em 0; color: #1f2937;
  --paper: #f9a8d4; --strip: #f193c4; --flap: #e46ba9; --shade: #9d174d4d;
  background: linear-gradient(var(--strip), color-mix(in srgb, var(--strip), var(--paper) 60%) 0.146em, transparent 0.146em), linear-gradient(-45deg, transparent 0.167em, var(--paper) 0);
  filter: drop-shadow(0 0.056em 0.09em var(--shade)) drop-shadow(0 0.013em 0.021em #00000026); }
/* Inter caps are 0.727em, so 0.668em sets a one 1/phi^1.5 (0.486) of the note tall, half a step below the x-height */
.app-one b { display: block; font: 800 0.668em/1 Inter, system-ui, sans-serif; letter-spacing: 0; }
.app-one::after { content: ""; position: absolute; right: 0; bottom: 0; width: 0.236em; height: 0.236em; border-top-left-radius: 0.09em;
  background: linear-gradient(-45deg, transparent 50%, var(--flap) 50%, color-mix(in srgb, var(--flap), var(--paper) 45%)); }
/* cutsq, the logo in the app: the sticky as a flat pink square with one corner cut, the bold Inter one of 5.1, then the script.
   The square is 1em, the logo height, and hangs 0.05em below the baseline like the Azeret one. */
.cutsq .app-one { background: #f9a8d4; filter: none; border-radius: 0; margin-bottom: -0.003em; clip-path: polygon(0 0, 100% 0, 100% 72%, 72% 100%, 0 100%); }
/* the dark flap of the sticky, folded into the cut: its legs are the 28% the clip path takes off */
.cutsq .app-one::after { width: 0.28em; height: 0.28em; }
