/* The kernel's own pages (pages.ts `shell`): the centred column a sign-in,
   a notice or a drop is drawn in, and the dashboard's frame. Everything a
   page holds is a part of @yaks/ui's kit, drawn by its pencil skin (_ui.css,
   shown at /style-guide); this is only what no other page draws. */
@layer tokens, base, components, sections;
@layer tokens {
/* Linen: yaks.app's colours. Light is a warm sheet of linen under cream
   cards, written in coffee, never black, with meadow green for what is lit
   and brick for a fault. Dark is the same room at night: a night-brown
   ground, cocoa cards, oat ink, moss for what is lit and rose for a fault.
   linen.ts holds the dark colours for a terminal.

   Its paints are named for what they look like (linen, cream, coffee,
   clay, taupe, shell, bark, cocoa, night, meadow, moss, brick, rose, dusk,
   sky, ember, blush, forest, oat), and a theme has more roles than a
   palette has hues, so roles share them: meadow is what is
   lit, what went well and who; brick a fault and the language's words;
   dusk something to know and a moment. yaks.app's own pages wear this
   theme (workers/yak/public). */
:root {
  color-scheme: light dark;
  --gap: 1rem;
  --radius: 4px;
  --measure: 38rem;
  --shadow: 0 12px 32px -16px light-dark(#5238283d, #1d1714b3);

  --font: 'Nunito', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, monospace;
  --size: 1.0625rem;
  --small: 0.9375rem;

  --bg: light-dark(#fdf7ee, #2b231f); /* linen; night */
  --surface: light-dark(#f7efe3, #392d27); /* a sheet behind the one in front */
  --card: light-dark(#fffbf5, #372c26); /* cream; cocoa */
  --border: light-dark(#efe3d2, #4d3d34); /* shell; bark */
  --border2: light-dark(#c9b7a6, #756255); /* the hairline, gone toward clay */

  --text: light-dark(#523828, #f1e6d8); /* coffee; oat */
  --muted: light-dark(#785b47, #c9b19c); /* clay; taupe */
  --dim: light-dark(#c9b19c, #785b47); /* taupe; clay */

  --accent: light-dark(#4c773e, #a7c080); /* meadow; moss */
  --link: light-dark(#4c773e, #a7c080);
  --heading: light-dark(#523828, #f1e6d8); /* the text's own ink */

  --info: light-dark(#34404a, #e5eef5); /* dusk; sky */
  --active: light-dark(#785b47, #f8e0c8); /* clay; blush */
  --positive: light-dark(#4c773e, #a7c080); /* meadow; moss */
  --negative: light-dark(#a8503f, #e67e80); /* brick; rose */
  --caution: light-dark(#a8503f, #e67e80); /* brick; rose */
  --special: light-dark(#785b47, #c9b19c); /* clay; taupe */

  --number: light-dark(#4e3b32, #f8e0c8); /* ember; blush */
  --literal: light-dark(#a8503f, #e67e80); /* brick; rose */
  --time: light-dark(#34404a, #e5eef5); /* dusk; sky */
  --who: light-dark(#4c773e, #a7c080); /* meadow; moss */

  --keyword: light-dark(#a8503f, #e67e80); /* brick; rose */
  --string: light-dark(#4c773e, #a7c080); /* meadow; moss */
  --fn: light-dark(#34404a, #fffbf5); /* dusk; cream */
  --type: light-dark(#4e3b32, #f8e0c8); /* ember; blush */
  --attr: light-dark(#785b47, #c9b19c); /* clay; taupe */

  --hue-0: light-dark(#4c773e, #a7c080); /* meadow; moss */
  --hue-1: light-dark(#4e3b32, #f8e0c8); /* ember; blush */
  --hue-2: light-dark(#34404a, #e5eef5); /* dusk; sky */
  --hue-3: light-dark(#a8503f, #e67e80); /* brick; rose */
  --hue-4: light-dark(#785b47, #c9b19c); /* clay; taupe */
  --hue-5: light-dark(#33493c, #f1e6d8); /* forest; oat */
}
@supports not (color: light-dark(#000, #fff)) {
:root {
  --shadow: 0 12px 32px -16px #5238283d;
  --bg: #fdf7ee;
  --surface: #f7efe3;
  --card: #fffbf5;
  --border: #efe3d2;
  --border2: #c9b7a6;
  --text: #523828;
  --muted: #785b47;
  --dim: #c9b19c;
  --accent: #4c773e;
  --link: #4c773e;
  --heading: #523828;
  --info: #34404a;
  --active: #785b47;
  --positive: #4c773e;
  --negative: #a8503f;
  --caution: #a8503f;
  --special: #785b47;
  --number: #4e3b32;
  --literal: #a8503f;
  --time: #34404a;
  --who: #4c773e;
  --keyword: #a8503f;
  --string: #4c773e;
  --fn: #34404a;
  --type: #4e3b32;
  --attr: #785b47;
  --hue-0: #4c773e;
  --hue-1: #4e3b32;
  --hue-2: #34404a;
  --hue-3: #a8503f;
  --hue-4: #785b47;
  --hue-5: #33493c;
}
@media (prefers-color-scheme: dark) {
:root {
  --shadow: 0 12px 32px -16px #1d1714b3;
  --bg: #2b231f;
  --surface: #392d27;
  --card: #372c26;
  --border: #4d3d34;
  --border2: #756255;
  --text: #f1e6d8;
  --muted: #c9b19c;
  --dim: #785b47;
  --accent: #a7c080;
  --link: #a7c080;
  --heading: #f1e6d8;
  --info: #e5eef5;
  --active: #f8e0c8;
  --positive: #a7c080;
  --negative: #e67e80;
  --caution: #e67e80;
  --special: #c9b19c;
  --number: #f8e0c8;
  --literal: #e67e80;
  --time: #e5eef5;
  --who: #a7c080;
  --keyword: #e67e80;
  --string: #a7c080;
  --fn: #fffbf5;
  --type: #f8e0c8;
  --attr: #c9b19c;
  --hue-0: #a7c080;
  --hue-1: #f8e0c8;
  --hue-2: #e5eef5;
  --hue-3: #e67e80;
  --hue-4: #c9b19c;
  --hue-5: #f1e6d8;
}
}
}

/* What every theme derives the same way: half its gap, a faint wash of its
   text, and the touch-target floor, which grows under a coarse pointer (fat
   fingers get fat targets, and only there).

   And the type every part reads, which a theme may set: --size for what a
   thing says, --small for the line that describes it, and nothing smaller.
   Headings climb from --size by one ratio, --scale, a step each: --h3, --h2,
   --h1. Every heading reads them, prose or part, so a page's h1 is the same
   size wherever it is drawn.
   Text comes in three inks. --text is what a thing says; --muted is what
   describes it (a key, a heading over a column, a fact, a stamp, an id, a
   count), and reads on every floor; --dim is only for what is not there (a
   nil, a ghost, a placeholder, a disabled step). The mono face is for what a
   person would copy or type (an id, a sha, code, a raw stored value), never
   for a label, a moment said the human way, or a count. A part that steps
   back is muted, small or both; never mono to look quiet, and never dim.
   And the width of what sits beside a page (a chat, what an agent gets):
   --side, never narrower than --side-min. */
:where(:root) {
  --half-gap: calc(var(--gap) / 2);
  --soft: color-mix(in srgb, var(--text) 6%, transparent);
  --tap: 0px;
  --size: 14px;
  --small: 12px;
  --scale: 1.2;
  --h3: calc(var(--size) * var(--scale));
  --h2: calc(var(--h3) * var(--scale));
  --h1: calc(var(--h2) * var(--scale));
  --side: 26rem;
  --side-min: 18rem;
}
@media (pointer: coarse) {
  :where(:root) {
    --tap: 2.5rem;
  }
}

}
@layer base {
/* Pencil: yaks.app's drawing, in place of the kit's document defaults. A
   part worth outlining is drawn: a graphite line around it with slightly
   rounded corners (--radius), given the paper's tooth by pencil.svg, which
   every drawn line goes through (--drawn). What can be pressed sits on a
   hatch it slides onto. What is typed into is a well pressed into the
   paper. A surface is flat. One grain of paper, yaks.app's own tile, lies
   over every page (paper/grain.css, laid over this).

   Everything here is :where() or a custom property, so any part's rule, and
   any page's, still wins. */
:root {
  --grain: url(_ui/packages/ui/pencil/paper.e48c5467b4.webp);
  --grain-opacity: .07;
  --drawn: url(_ui/packages/ui/pencil/pencil.8b0be94b38.svg#line);

  --graphite: color-mix(in srgb, var(--text) 88%, transparent);
  --stroke: 1.5px; /* the weight of a drawn line */
  --lift: 4px; /* how far what can be pressed sits off its hatch */
  --hatch: repeating-linear-gradient(-45deg, var(--graphite) 0 1px,
    transparent 1px 3px);
  /* A drawn rule is a line through the middle of a box --room taller on
     each side, so the pencil's wander stays inside what it draws. */
  --room: 4px;
  --rule: linear-gradient(var(--graphite) 0 0) center / 100% var(--stroke)
    no-repeat;
  /* A well: a fill a little darker than the paper, pressed in. */
  --well: light-dark(
    color-mix(in srgb, var(--card), var(--border) 45%),
    color-mix(in srgb, var(--card), var(--bg) 65%)
  );
  --shade: light-dark(
    color-mix(in srgb, #523828 24%, transparent),
    color-mix(in srgb, #1d1714 70%, transparent)
  ); /* coffee; soot: what a well's hollow is */
  --hollow: inset 0 2px 4px var(--shade); /* how deep a well sits */
  /* How tall a press or a field stands; a part that holds a row of them
     smaller re-points it. */
  --control-height: 2.25rem;
}
@supports not (color: light-dark(#000, #fff)) {
:root {
  --well: color-mix(in srgb, var(--card), var(--border) 45%);
  --shade: color-mix(in srgb, #523828 24%, transparent);
}
@media (prefers-color-scheme: dark) {
:root {
  --well: color-mix(in srgb, var(--card), var(--bg) 65%);
  --shade: color-mix(in srgb, #1d1714 70%, transparent);
}
}
}

:where(body) {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: var(--size) / 1.6 var(--font);
  -webkit-font-smoothing: antialiased;
}

:where([hidden]) {
  display: none !important;
}

/* A control is pressed, not read: clicking or tapping one never selects its
   words. Links in prose, addresses, numbers and code stay selectable. */
:where(button, summary, label, select, [role='button'], [role='tab'], [role='menuitem'], .Button) {
  -webkit-user-select: none;
  user-select: none;
}

/* What is drawn wears its outline on ::after: a graphite line through the
   pencil, in --pencil where a part asks for another colour and dashed where
   --pencil-style says so. Each starts from a solid graphite line, so none
   takes the line of a box it sits in. */
:where(.Button, .Card, a.Chip, .Empty, .Drop_Zone) {
  --pencil: initial;
  --pencil-style: initial;
}
:where(.Button, .Card, a.Chip, .Empty, .Drop_Zone)::after {
  content: '';
  position: absolute;
  inset: -1px;
  border: var(--stroke) var(--pencil-style, solid)
    var(--pencil, var(--graphite));
  border-radius: var(--radius);
  filter: var(--drawn);
  pointer-events: none;
}

/* The grain: one tile of paper, speckled in ink and cream, over the whole
   page and scrolling with it. It is drawn above everything, faint enough to
   read through, and never takes a press. The tile is --grain, at
   --grain-opacity: each skin that lays this names its own (paper/base.css,
   pencil/base.css). */
:where(html) {
  position: relative;
  min-height: 100%;
}
:where(html)::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2147483647;
  background: var(--grain) 0 0 / 256px;
  opacity: var(--grain-opacity);
  pointer-events: none;
}

}
@layer components {
/* Pencil's press, yaks.app's: a flat fill on a hatch, the hatch what an
   offset copy of it would show past its right and bottom edges, and its
   outline drawn in pencil on ::after (--pencil, --pencil-style: each part
   starts from a solid graphite line, so none takes the line of a box it sits
   in). A hover lifts the button off the hatch and a press slides it onto it;
   the hatch stays put. It stands --control-height tall, as a field does,
   padded by --control-pad-inline, which a part that holds a row of them
   re-points.

   Plain is paper; -go, the one to press, the accent; -quiet steps back
   beside another and reads as a link, with no fill, outline or hatch.
   -danger says its word in the negative, and -add, which offers what is not
   there yet, is muted and its line dashed. The fill and the ink ride
   --button-fill and --button-ink, so a part can re-point them. */
.Button {
  box-sizing: border-box;
  height: var(--control-height);
  padding: 0 var(--control-pad-inline, .75rem);
  font: inherit;
  line-height: 1.25;
  vertical-align: middle;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .35rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: var(--button-fill, var(--card));
  color: var(--button-ink, var(--text));
  font-weight: 800;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}
.Button::before {
  content: '';
  position: absolute;
  inset: calc(var(--lift) - 1px) calc(-1px - var(--lift))
    calc(-1px - var(--lift)) calc(var(--lift) - 1px);
  border-radius: var(--radius);
  background: var(--hatch);
  clip-path: polygon(calc(100% - var(--lift)) 0, 100% 0, 100% 100%, 0 100%,
    0 calc(100% - var(--lift)), calc(100% - var(--lift))
    calc(100% - var(--lift)));
  pointer-events: none;
}
.Button:hover:not(:disabled, [aria-pressed='true']) {
  --lift: 5px;
  transform: translate(-1px, -1px);
  background: color-mix(in srgb, var(--button-fill, var(--card)),
    white 10%);
}
.Button:active:not(:disabled),
.Button[aria-pressed='true'] {
  --lift: 1.5px;
  transform: translate(2.5px, 2.5px);
}
.Button:disabled {
  --lift: 0px;
  opacity: .55;
  cursor: not-allowed;
}
.Button-go {
  --button-fill: var(--accent);
  --button-ink: var(--bg);
}
.Button-quiet {
  --button-ink: var(--accent);
}
.Button-quiet,
.Button-quiet:hover:not(:disabled, [aria-pressed='true']),
.Button-quiet:active:not(:disabled) {
  --lift: 0px;
  padding: 0;
  background: none;
  font-weight: inherit;
  text-decoration: underline;
  transform: none;
}
.Button-quiet::before,
.Button-quiet::after {
  content: none;
}
.Button-add {
  --pencil-style: dashed;
  --button-ink: var(--muted);
}
.Button-add:hover {
  --button-ink: var(--text);
}
.Button-danger {
  --button-ink: var(--negative);
}
.Button-go.Button-danger {
  --button-fill: var(--negative);
  --button-ink: var(--bg);
}

}
@layer components {
/* Pencil's field is a well: darker than the paper, a little hollow, its edge
   drawn in pencil, as tall as a press beside it (--control-height). The
   pencil keeps what lies inside the edge as it is, so what is typed stays
   crisp. Focus draws the edge in the accent. */
.Field {
  box-sizing: border-box;
  height: var(--control-height);
  min-width: 0;
  max-width: 100%;
  padding: 0 var(--control-pad-inline, .75rem);
  border: var(--stroke) solid var(--graphite);
  border-radius: var(--radius);
  background: var(--well);
  box-shadow: var(--hollow);
  color: var(--text);
  font: inherit;
  line-height: 1.25;
  vertical-align: middle;
  filter: var(--drawn);
}
.Field:focus-visible {
  outline: 0;
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent), var(--hollow);
}
select.Field {
  cursor: pointer;
}
select.Field:not(:disabled):hover {
  border-color: var(--accent);
}
/* A textarea is as tall as what is typed in it, from two controls' height
   up to most of the window, where it starts to scroll. */
textarea.Field {
  field-sizing: content;
  height: auto;
  min-height: calc(var(--control-height) * 2);
  max-height: 60vh;
  padding-block: .5rem;
  vertical-align: top;
}
.Field:disabled {
  opacity: .55;
  cursor: not-allowed;
}
/* A bare field belongs inside a part already drawn: no well, no edge. */
.Field-bare,
.Field-bare:focus-visible {
  height: auto;
  min-height: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  filter: none;
}

}
@layer components {
/* Pencil's chip, yaks.app's: a word on a card, edged in a hairline. A link
   chip is underlined in the accent and drawn in pencil (on ::after, from a
   solid graphite line, as a press is), and a hover washes it in the accent;
   pressed, not read, its words never select. -quiet is a label on the floor
   (the address in a window bar), -code words to copy, in the mono face. A
   hue (-0 … -5) inks and washes it in its colour, a link too; a ghost is
   dim, its edge dashed. What a variant changes rides a --chip-* property. */
.Chip {
  display: inline-block;
  padding: var(--chip-pad, .3rem .75rem);
  border: var(--chip-edge, 1px solid var(--border));
  border-radius: var(--radius);
  background: var(--chip-fill, var(--card));
  color: var(--chip-ink, var(--chip-hue, var(--text)));
  font-family: var(--chip-font, inherit);
  font-size: var(--chip-size, var(--small));
  font-weight: var(--chip-weight, 600);
  line-height: 1.4;
  vertical-align: middle;
  text-decoration: none;
}
a.Chip {
  --chip-ink: var(--chip-hue, var(--accent));
  --chip-edge: 1px solid transparent;
  --chip-weight: 700;
  position: relative;
  text-decoration: underline;
  text-underline-offset: .18em;
}
:where(a.Chip) {
  -webkit-user-select: none;
  user-select: none;
}
a.Chip:hover {
  --pencil: var(--accent);
  --chip-fill: color-mix(in srgb, var(--accent) 7%, var(--card));
}
a.Chip:active {
  transform: translate(1px, 1px);
}
a.Chip:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}
.Chip_Tag {
  margin-left: .5rem;
  color: var(--muted);
  font-weight: 400;
  font-size: .85em;
}
.Chip-quiet {
  --chip-fill: var(--bg);
  --chip-ink: var(--muted);
  --chip-edge: 0;
  --chip-pad: 0.2rem 0.9rem;
  --chip-size: var(--small);
  --chip-weight: 600;
}
.Chip-code {
  --chip-pad: .2rem .5rem;
  --chip-fill: var(--bg);
  --chip-edge: 0;
  --chip-font: var(--mono);
  --chip-size: var(--small);
}
.Chip-0 {
  --chip-hue: var(--hue-0);
}
.Chip-1 {
  --chip-hue: var(--hue-1);
}
.Chip-2 {
  --chip-hue: var(--hue-2);
}
.Chip-3 {
  --chip-hue: var(--hue-3);
}
.Chip-4 {
  --chip-hue: var(--hue-4);
}
.Chip-5 {
  --chip-hue: var(--hue-5);
}
:is(.Chip-0, .Chip-1, .Chip-2, .Chip-3, .Chip-4, .Chip-5) {
  --chip-fill: color-mix(in srgb, var(--chip-hue) 12%, var(--card));
}
.Chip-ghost {
  --chip-ink: var(--dim);
  --chip-fill: none;
  --chip-edge: 1px dashed var(--border2);
}

}
@layer components {
/* Pencil's row of chips, yaks.app's: a handful of notes, wrapping. */
.Chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.625rem;
}

}
@layer components {
/* An address: muted, the name in it the text's own ink and weighted. */
.Address {
  color: var(--muted);
  font-weight: normal;
}
.Address_Name {
  color: var(--text);
  font-weight: 600;
}

/* Pencil's address, laid over the kit's: the name in it in yaks.app's
   heaviest weight. */
.Address_Name {
  font-weight: 800;
}

}
@layer components {
/* A list of rows, close together. A nested list hangs off a rule. */
.Rows {
  display: grid;
  gap: 1px;
  min-width: 0;
}
.Rows-nested {
  margin-left: var(--half-gap);
  padding-left: var(--half-gap);
  border-left: 1px solid var(--border2);
}
.Rows_Item {
  min-width: 0;
}
.Rows_More {
  font-size: var(--small);
  color: var(--muted);
}

/* What is kept but no longer live: every word in it muted, links too. */
.Rows-quiet,
.Rows-quiet :is(a, .Tile_Title, .Body) {
  color: var(--muted);
}

/* A feed of unlike things: each entry has its own edge and breathing room. */
.Rows-ruled > .Rows_Item {
  padding: var(--half-gap) 0;
  border-bottom: 1px solid var(--border2);
}
.Rows_Kind {
  font-size: var(--small);
  color: var(--muted);
}

/* An entry's whole surface opens it, including a renderer's secondary text. */
.Rows_Link {
  display: block;
  color: var(--text);
  text-decoration: none;
  min-width: 0;
  border-radius: var(--radius);
}
.Rows_Link:hover {
  background: var(--soft);
}
.Rows_Link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* A list put in order by dragging its rows. A row that can be picked up says
   so under the pointer, and a line says where a dragged one would land. */
.Rows-ordered > .Rows_Item[draggable='true'] {
  cursor: grab;
}
.Rows_Item-before {
  box-shadow: 0 -2px 0 var(--accent);
}
.Rows_Item-after {
  box-shadow: 0 2px 0 var(--accent);
}

/* A row that opens in place: a glyph pressed beside what it says, and, while
   open, what it opens, beneath it, hung off a rule. */
.Rows_Line {
  display: flex;
  align-items: center;
  gap: var(--half-gap);
  min-width: 0;
}
.Rows_Line > :last-child {
  flex: 1;
  min-width: 0;
}
.Rows_Toggle {
  font: inherit;
  color: var(--muted);
  background: none;
  border: 0;
  border-radius: var(--radius);
  padding: 0 4px;
  min-height: var(--tap);
  cursor: pointer;
}
.Rows_Toggle:hover {
  color: var(--text);
  background: var(--soft);
}
.Rows_Toggle:focus-visible {
  outline: 2px solid var(--accent);
}
.Rows_Toggle:disabled {
  visibility: hidden;
}
.Rows_Detail {
  display: grid;
  gap: var(--half-gap);
  margin: var(--half-gap) 0 var(--gap) var(--gap);
  padding-left: var(--gap);
  border-left: 1px solid var(--border2);
  min-width: 0;
}

/* A row of like things: a thing's name over what describes it, and what
   acts on it at the far side, under it where there is no room beside. */
.Rows_Item:where(:has(> .Rows_Main)) {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--half-gap) var(--gap);
}
.Rows_Main {
  display: grid;
  flex: 1 1 12rem;
  gap: 2px;
  min-width: 0;
  overflow-wrap: anywhere;
}
.Rows_Name {
  color: var(--text);
  font-weight: 700;
}
.Rows_Meta {
  color: var(--muted);
  font-size: var(--small);
}
.Rows_Actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--half-gap);
  margin-left: auto;
}
.Rows_Actions form {
  display: contents;
}

/* Like things in rows, hairlines between them: each row its name and what
   describes it on the left, what acts on it on the right, its controls a
   size down. The kit's rows sit a pixel apart; these meet at the hairline.
   In a card the rows run to its edges (pencil/Card.css). */
.Rows {
  gap: 0;
  min-width: auto;
  margin: 0;
  padding: 0;
  list-style: none;
}
.Rows_Item {
  --control-height: 2rem;
  --control-pad-inline: 0.7rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1rem;
  min-width: auto;
  padding: 0.75rem 0;
  border-top: 1px solid var(--border);
}
.Rows_Item:first-child {
  padding-top: 0;
  border-top: 0;
}
.Rows_Item:last-child {
  padding-bottom: 0;
}
.Rows_Main {
  gap: 0.15rem;
  line-height: 1.45;
}
.Rows_Meta {
  font-size: var(--fine, var(--small));
}
.Rows_Actions {
  gap: 0.5rem;
  margin: 0 0 0 auto;
}
.Rows_Actions .Button {
  font-size: var(--fine, var(--small));
}

}
@layer components {
/* A card: one surface holding related things, flat on the page. Depth
   belongs to what is pressed, so a card casts no shadow; its pencil box is
   what draws it. What it holds stacks a gap apart, never by margins of its
   own, and its head, when it has one, runs edge to edge across the top,
   ruled off under it: what it is on the left, its actions on the right.

   Its box is drawn as everything outlined is (base.css). A page's own
   surface is drawn by being a card. */
.Card {
  --pad-block: 1rem;
  --pad-inline: 1.25rem;
  position: relative;
  display: grid;
  align-content: start;
  gap: 0.75rem;
  min-width: 0;
  padding: var(--pad-block) var(--pad-inline);
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: var(--card);
  overflow-wrap: break-word;
}
.Card > * {
  min-width: 0;
  margin: 0;
}

/* The head: a mark, the title, how it stands, and then whatever acts on
   the whole card, pushed to the right. Its controls are a size down, so a
   head is one compact line however many it holds; it wraps on a phone. */
.Card_Head {
  --control-height: 2rem;
  --control-pad-inline: 0.7rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
  min-height: 3rem;
  position: relative;
  margin: calc(-1 * var(--pad-block)) calc(-1 * var(--pad-inline)) 0;
  padding: 0.5rem var(--pad-inline);
}
/* The rule under it meets the card's sides. */
.Card_Head::after {
  content: '';
  position: absolute;
  inset: auto -1px calc(-1 * var(--room));
  height: calc(var(--stroke) + 2 * var(--room));
  background: var(--rule);
  filter: var(--drawn);
}
.Card_Head:last-child {
  margin-bottom: calc(-1 * var(--pad-block));
}
.Card_Head:last-child::after {
  content: none;
}
.Card_Title {
  margin: 0;
  color: var(--text);
  font-size: 1rem;
  font-weight: 800;
  line-height: 1.3;
}
.Card_Title a {
  color: inherit;
  text-decoration: none;
}
.Card_Title a:hover {
  color: var(--accent);
  text-decoration: underline;
}
.Card_Mark {
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
}
.Card_Actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0 auto;
}
.Card_Actions form {
  display: contents;
}
.Card_Actions .Button {
  font-size: var(--fine, var(--small));
}

/* What the card is, in a line, under its head. */
.Card_Sub {
  color: var(--muted);
  font-size: var(--small);
}

/* Rows in a card run to its edges, the hairlines between them meeting its
   sides. */
.Card > .Rows {
  margin-inline: calc(-1 * var(--pad-inline));
}
.Card > .Rows > .Rows_Item {
  padding-inline: var(--pad-inline);
}

}
@layer components {
/* A pip: a disc whose shape says a state and whose tone colours it. Shape
   and tone are separate variants, so a state is at most one of each. The
   glyphs are pseudo-elements drawn in floor ink, so they read as cutouts. */
.Dot {
  --dot: var(--dim);
  display: inline-block;
  position: relative;
  flex: none;
  width: 0.72em; /* em: the pip rides its line's font */
  height: 0.72em;
  border-radius: 50%;
  border: max(1px, 0.09em) solid var(--dot);
  background: var(--dot);
}
.Dot::before,
.Dot::after {
  position: absolute;
}

/* The shapes. */
.Dot-ring {
  background: transparent;
}
.Dot-dashed {
  background: transparent;
  border-style: dashed;
}
.Dot-half {
  background: linear-gradient(90deg, var(--dot) 50%, transparent 0);
}
/* Something happening right now: the full disc breathes. */
.Dot-pulse {
  animation: DotPulse 2.2s ease-out infinite;
}
@keyframes DotPulse {
  from {
    box-shadow: 0 0 0 0 color-mix(in srgb, var(--dot) 55%, transparent);
  }
  to {
    box-shadow: 0 0 0 0.45em color-mix(in srgb, var(--dot) 0%, transparent);
  }
}
@media (prefers-reduced-motion: reduce) {
  .Dot {
    animation: none; /* the full disc still says it; only the breath goes */
  }
}
.Dot-check::after {
  content: '';
  left: 50%;
  top: 50%;
  width: 0.3em;
  height: 0.16em;
  border-left: 0.09em solid var(--bg);
  border-bottom: 0.09em solid var(--bg);
  transform: translate(-50%, -65%) rotate(-45deg);
}
.Dot-cross::before,
.Dot-cross::after {
  content: '';
  left: 50%;
  top: 50%;
  width: 0.09em;
  height: 0.38em;
  border-radius: 0.04em;
  background: var(--bg);
}
.Dot-cross::before {
  transform: translate(-50%, -50%) rotate(45deg);
}
.Dot-cross::after {
  transform: translate(-50%, -50%) rotate(-45deg);
}
.Dot-alert::before {
  content: '';
  left: 50%;
  top: 0.1em;
  width: 0.09em;
  height: 0.24em;
  border-radius: 0.04em;
  translate: -50%;
  background: var(--bg);
}
.Dot-alert::after {
  content: '';
  left: 50%;
  bottom: 0.08em;
  width: 0.1em;
  height: 0.1em;
  border-radius: 50%;
  translate: -50%;
  background: var(--bg);
}

/* The tones. */
.Dot-info {
  --dot: var(--info);
}
.Dot-active {
  --dot: var(--active);
}
.Dot-positive {
  --dot: var(--positive);
}
.Dot-negative {
  --dot: var(--negative);
}
.Dot-caution {
  --dot: var(--caution);
}
.Dot-accent {
  --dot: var(--accent);
}
.Dot-special {
  --dot: var(--special);
}

}
@layer components {
/* How something stands: a word beside a dot. The word describes, so it is
   small and muted; the dot's tone says the state. */
.State {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  color: var(--muted);
  font-size: var(--small);
  line-height: 1.3;
}

/* How something stands, as a word in its role's colour beside a dot of the
   same: -positive when it works, -negative when it needs the person. What
   works is said in the accent, the colour of what is lit. */
.State {
  gap: 0.35rem;
  color: var(--state, var(--muted));
  font-size: var(--fine, var(--small));
  font-weight: 700;
}
.State > .Dot {
  width: 0.5rem;
  height: 0.5rem;
  border: 0;
  background: currentColor;
}
.State-positive,
.State-accent {
  --state: var(--accent);
}
.State-negative {
  --state: var(--negative);
}
.State-info {
  --state: var(--info);
}
.State-active {
  --state: var(--active);
}
.State-caution {
  --state: var(--caution);
}
.State-special {
  --state: var(--special);
}

}
@layer components {
/* A heading over a run of cards: what they share, small and muted, so the
   cards' own titles lead. */
.Group {
  margin: 0;
  color: var(--muted);
  font-size: var(--small);
  font-weight: 700;
}

/* A heading over a run of cards that belong together, a gap after the run
   before it. */
.Group {
  margin: var(--gap) 0 0;
}
.Group:first-child {
  margin-top: 0;
}

}
@layer components {
/* Pencil's form: yaks.app's spacing, its fields at most 34rem wide and their
   hints a step under the small type (--fine, yaks.app's). */
.Form {
  display: grid;
  gap: .875rem;
  margin: 0;
}
.Form_Field {
  display: grid;
  gap: .35rem;
  min-width: 0;
  max-width: 34rem;
}
.Form_Label {
  margin: 0;
  color: var(--text);
  font-size: var(--small);
  font-weight: 700;
}
.Form_Optional {
  color: var(--muted);
  font-weight: 400;
}
.Form_Field > .Field {
  width: 100%;
}
.Form_Hint {
  margin: 0;
  color: var(--muted);
  font-size: var(--fine, var(--small));
}
/* A value shown where its control would be, which nobody changes here: its
   words as they are, every line and long word kept inside the field. */
.Form_Value {
  margin: 0;
  color: var(--text);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.Form_Value-none {
  color: var(--dim);
}
/* One field and the button that sends it, on one line while they fit. */
.Form_Line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem;
  min-width: 0;
  margin: 0;
}
.Form_Line > .Field,
.Form_Line > .At {
  flex: 1 1 12rem;
}
.Form_Actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem;
}

}
@layer components {
/* Pencil's field with a fixed ending: yaks.app's spacing. */
.At {
  display: flex;
  align-items: center;
  gap: .35rem;
  min-width: 0;
}
.At > .Field {
  flex: 1 1 auto;
}
.At_End {
  flex: none;
  color: var(--muted);
}

}
@layer components {
/* Pencil's drop zone: a place for something rather than a thing, so its
   pencil line is dashed and light (--pencil, --pencil-style, on ::after, as
   every drawn part wears its line), solid in the accent while files are held
   over it. What is chosen sits under it on wells, a step under the small
   type where it describes (--fine, yaks.app's). */
.Drop {
  display: grid;
  gap: .5rem;
  min-width: 0;
}
.Drop_Zone {
  --pencil: var(--border2);
  --pencil-style: dashed;
  position: relative;
  display: grid;
  place-items: center;
  gap: .25rem;
  min-height: 6rem;
  padding: 1.25rem 1rem;
  border-radius: var(--radius);
  background: var(--bg);
  text-align: center;
  cursor: pointer;
}
.Drop_Zone:hover,
.Drop_Zone:has(.Drop_File:focus-visible) {
  --pencil: var(--accent);
}
.Drop_Zone:has(.Drop_File:focus-visible) {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.Drop_Zone-over {
  --pencil: var(--accent);
  --pencil-style: solid;
  background: var(--card);
}
.Drop_Zone:has(.Drop_File:disabled) {
  opacity: .55;
  cursor: not-allowed;
}
.Drop_File {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.Drop_Say {
  color: var(--text);
}
.Drop_Choose {
  color: var(--accent);
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: .2em;
}
.Drop_Hint {
  color: var(--muted);
  font-size: var(--fine, var(--small));
}
.Drop_Chosen {
  display: grid;
  gap: .35rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.Drop_Chosen:empty {
  display: none;
}
.Drop_Item {
  --control-height: 2rem;
  --control-pad-inline: .7rem;
  display: flex;
  align-items: center;
  gap: .75rem;
  min-width: 0;
  padding: .35rem .5rem;
  border-radius: var(--radius);
  background: var(--well);
}
.Drop_Picture {
  flex: none;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--radius);
  object-fit: cover;
}
.Drop_Name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  color: var(--text);
  font-weight: 700;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.Drop_Size {
  flex: none;
  color: var(--muted);
  font-size: var(--fine, var(--small));
}
.Drop_Item > .Button {
  flex: none;
  font-size: var(--fine, var(--small));
}
/* What was left out, past the input's ceilings. */
.Drop_Said {
  margin: 0;
  color: var(--muted);
  font-size: var(--fine, var(--small));
}
.Drop_Said:empty {
  display: none;
}
/* A file of a kind that is not read, with a line that says so. */
.Drop_Note {
  flex-basis: 100%;
  color: var(--muted);
  font-size: var(--fine, var(--small));
}
.Drop_Item-unread {
  flex-wrap: wrap;
}
/* A gathering part (a chat app's message box): it takes a drop or a paste
   anywhere on it, and what it holds sits along its top as chips, a picture
   as itself and any other file as its kind and name, each with a way to take
   it back. */
.Drop-gather {
  position: relative;
}
.Drop-over {
  outline: 2px dashed var(--accent);
  outline-offset: 2px;
}
.Drop-gather .Drop_Chosen {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
}
.Drop-gather .Drop_Chosen:empty {
  display: none;
}
.Drop-gather .Drop_Item {
  position: relative;
  gap: .5rem;
  max-width: 16rem;
  padding: .35rem 2rem .35rem .35rem;
}
.Drop-gather .Drop_Picture {
  width: 3.5rem;
  height: 3.5rem;
}
.Drop-gather .Drop_Item > .Button {
  position: absolute;
  top: .2rem;
  right: .2rem;
  --control-height: 1.6rem;
  --control-pad-inline: .45rem;
}
.Drop_Kind {
  flex: none;
  display: grid;
  place-items: center;
  min-width: 2.5rem;
  height: 2.5rem;
  padding-inline: .3rem;
  border-radius: var(--radius);
  background: var(--card);
  color: var(--muted);
  font-size: var(--fine, var(--small));
  font-weight: 700;
}

}
@layer components {
/* Pencil's fold: yaks.app's spacing, and markdown someone wrote in it (a
   Body, theirs.ts in yaks.app), such as how to get a key, set close and
   ending where the body does. */
.More > summary {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  color: var(--accent);
  font-size: var(--small);
  font-weight: 700;
  cursor: pointer;
  list-style: none;
}
.More > summary::-webkit-details-marker {
  display: none;
}
.More > summary::before {
  content: '';
  flex: none;
  width: .4rem;
  height: .4rem;
  border: solid currentColor;
  border-width: 0 2px 2px 0;
  transform: rotate(-45deg);
  transition: transform .15s;
}
.More[open] > summary::before {
  transform: rotate(45deg);
}
.More_Body {
  display: grid;
  gap: .875rem;
  margin-top: .75rem;
}
.More_Body > *,
.More_Body > .Body > :last-child {
  margin: 0;
}
.More_Body > .Body {
  display: grid;
  gap: .625rem;
}
.More_Body > .Body :is(p, ol, ul, pre) {
  margin: 0;
}
.More_Body > .Body :is(ol, ul) {
  display: grid;
  gap: .375rem;
  padding-inline-start: 1.4rem;
}
.More_Body > .Body li {
  display: grid;
  gap: .375rem;
}
.More_Body > .Body ol {
  list-style: decimal;
}
.More_Body > .Body ul {
  list-style: disc;
}
.More_Body > .Body pre {
  padding: .6rem .8rem;
  background: var(--card);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

}
@layer components {
/* The text of a thing: the ink at a reading measure, its paragraphs and
   quotes as the base sets prose. A short one is the gist: muted, smaller. */
.Body {
  min-width: 0;
  max-width: var(--measure);
  color: var(--text);
  line-height: 1.5;
  overflow-wrap: anywhere;
}
.Body-short {
  color: var(--muted);
  font-size: var(--small);
}
/* A text a press types into: the pointer says so, a text cursor over a
   faint wash. */
.Body-typed {
  cursor: text;
  border-radius: var(--radius);
}
.Body-typed:hover {
  background: var(--soft);
}
/* A document's source: its lines kept and wrapped at the measure, every
   character where it stands, smaller, in the face of what is typed. */
.Body-source > pre {
  margin: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font-size: var(--small);
  line-height: 1.5;
}

/* Pencil's body of text takes the page's measure and type, as yaks.app's
   rendered markdown always has: the kit's measure, line and ink give way to
   whatever holds it, a page's prose or a reply. */
.Body {
  min-width: auto;
  max-width: none;
  color: inherit;
  line-height: inherit;
  overflow-wrap: inherit;
}

}
@layer components {
/* A line said back, small and muted; a refusal in the negative. Empty, it
   takes no room. */
.Notice {
  margin: 0;
  color: var(--muted);
  font-size: var(--small);
}
.Notice:empty {
  display: none;
}
.Notice-negative {
  color: var(--negative);
}

}
@layer components {
/* Something at work: the yak doing it (yaks.app's mascot), then the words
   that say what it is, in the ink of wherever it sits. */
.Loading {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.Loading_Mark,
.Loading_Mark img {
  display: block;
  flex: none;
  width: 40px;
  height: 40px;
}

}
@layer components {
/* Pencil's words to copy, yaks.app's: a strip of the floor a control tall,
   the words in the face around them, and the button beside it a paper press
   inked in the accent, a size down (pages.ts `copyable`). */
.Copy {
  display: flex;
  align-items: center;
  gap: .5rem;
  min-width: 0;
}
.Copy_Text {
  flex: 1;
  min-width: 0;
  min-height: var(--control-height);
  padding: .4rem .75rem;
  background: var(--bg);
  color: var(--text);
  overflow-wrap: anywhere;
  user-select: all;
}
/* In its Copy, so it outranks the press it wears, whichever sheet comes
   first. */
.Copy .Copy_Go {
  --button-ink: var(--accent);
  flex: none;
  font-size: var(--fine, var(--small));
}

}
@layer components {
/* Nothing here yet: what will be, and how to start. Its pencil line is
   dashed and light, a place for something rather than a thing. */
.Empty {
  --pencil: var(--border2);
  --pencil-style: dashed;
  position: relative;
  display: grid;
  justify-items: center;
  gap: 0.5rem;
  padding: 2rem 1.25rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  color: var(--muted);
  text-align: center;
}
.Empty > * {
  max-width: 30rem;
  margin: 0;
}
.Empty h2 {
  color: var(--text);
  font-size: 1.05rem;
  font-weight: 800;
}

}
@layer components {
/* A report: a card whose head says the total where its actions would sit,
   then a chart of the days, its first and last day under it, and short
   lists side by side, each name cut short before it would push its count
   out of its column. */
.Report {
  gap: 1.25rem;
}
.Report_Total {
  flex: none;
  margin: 0 0 0 auto;
  color: var(--text);
  font-size: var(--h3);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
}
.Report_Unit {
  color: var(--muted);
  font-size: var(--small);
  font-weight: 400;
}
.Report_Plot {
  display: grid;
  gap: 0.35rem;
  margin: 0;
}
.Report_Span {
  display: flex;
  justify-content: space-between;
  color: var(--muted);
  font-size: var(--small);
}
.Report_Tops {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.5rem;
}
.Report_Column h3 {
  margin: 0 0 0.5rem;
  color: var(--muted);
  font-size: var(--small);
  font-weight: 700;
}
/* One column as wide as the list's own, so a long name is cut short with
   an ellipsis rather than widening the row past its column and over the
   next one; the count beside it keeps its whole width and one line. */
.Report_List {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.4rem;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--small);
}
.Report_List li {
  display: flex;
  justify-content: space-between;
  gap: 0.75rem;
}
.Report_List span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.Report_List b {
  flex: none;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
@media (max-width: 600px) {
  .Report_Tops {
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
  }
}

/* A report drawn yaks.app's way: its total a little larger and heavier, and
   what describes it a step under the small type. */
.Report_Total {
  font-size: 1.25rem;
  font-weight: 800;
}
.Report_Unit,
.Report_Span,
.Report_Column h3 {
  font-size: var(--fine, var(--small));
}

}
@layer components {
/* A chart's marks. A number's words keep the page's ink; the marks are drawn
   in the theme's roles. */
.Chart {
  position: relative;
  touch-action: pan-y;
}
/* The point a pointer, a finger or an arrow key is on (the page's listener
   sets data-on and --at), and the tip that says it, floating clear of
   whatever clips the chart. */
.Chart[data-on]::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--at);
  width: 1px;
  background: var(--muted);
  pointer-events: none;
}
.Chart-line {
  display: inline-block;
  vertical-align: middle;
}
.Chart-bars {
  display: block;
  height: 5rem;
  border-bottom: 1px solid var(--border2);
}
.Chart-bars .Chart_Plot {
  display: block;
  width: 100%;
  height: 100%;
}
.Chart_Line {
  fill: none;
  stroke: var(--muted);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.Chart_End,
.Chart_Bar {
  fill: var(--accent);
}
.Chart_Tip {
  position: fixed;
  z-index: 200;
  padding: 0.15rem 0.5rem;
  border-radius: var(--radius);
  background: var(--text);
  color: var(--card);
  font-size: var(--small);
  white-space: nowrap;
  pointer-events: none;
}

/* A chart in pencil: a graphite line through the pencil, ending in a dot on
   today, or a column a day over a hairline. A pointer over it is a
   crosshair, and the tip floats over every raised part of the page. */
.Chart {
  z-index: 1;
  cursor: crosshair;
}
.Chart:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.Chart-line {
  margin-left: 0.5rem;
  padding: 0.25rem 0;
  line-height: 0;
}
.Chart-line .Chart_Plot {
  filter: var(--drawn);
  overflow: visible;
}
.Chart-bars {
  border-bottom: 1px solid var(--border);
}
.Chart_Line {
  stroke: var(--graphite);
  stroke-width: var(--stroke);
}
.Chart_Tip {
  z-index: var(--float, 200);
  font-size: var(--fine, var(--small));
}

}
@layer components {
/* Pencil's tabs: physical tabs on one sheet. Each tab is drawn in pencil on
   its top and sides; the panel's own top line is every tab's foot, and the
   lit tab covers it, so tab and panel are one sheet. In a set (`TabSet`)
   native radios own selection, arrow keys too, so it works without script:
   the checked radio's tab is the lit one. */
.Tabs {
  display: flex;
  flex-wrap: wrap;
  column-gap: .3rem;
  position: relative;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}
.Tabs_Legend {
  margin-bottom: 1rem;
  padding: 0;
  color: var(--text);
  font-weight: 800;
  text-align: left;
}
.Tabs_Item {
  display: contents;
}
.Tabs_Item > input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.Tabs_Tab {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  min-width: 0;
  min-height: 3rem;
  overflow-wrap: normal;
  margin: .35rem 0 0;
  padding: .55rem .45rem;
  border: 1px solid transparent;
  border-bottom: 0;
  border-radius: var(--radius) var(--radius) 0 0;
  background: var(--surface);
  color: var(--muted);
  font: inherit; /* a button's, as a label's is */
  font-size: .85rem;
  font-weight: 700;
  line-height: 1.25;
  text-align: center;
  text-decoration: none; /* a tab that links reads as a tab */
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
}
.Tabs_Tab::after {
  content: '';
  position: absolute;
  inset: -1px -1px 0;
  border: var(--stroke) solid var(--graphite);
  border-bottom: 0;
  border-radius: var(--radius) var(--radius) 0 0;
  filter: var(--drawn);
  pointer-events: none;
}
@media (max-width: 480px) {
  .Tabs_Tab {
    padding-inline: .3rem;
    font-size: .8rem;
  }
}
.Tabs_Tab:hover,
.Tabs_Tab-hover {
  color: var(--text);
}
.Tabs_Panel {
  order: 1;
  flex: 1 1 100%;
  min-width: 0;
  position: relative;
  margin: 0;
  text-align: left;
  z-index: 1;
}
.Tabs_Tab-on,
.Tabs_Item > input:checked ~ .Tabs_Tab {
  margin-top: 0;
  padding-top: .9rem;
  background: var(--card);
  color: var(--text);
  z-index: 2;
}
/* The gap the lit tab opens in the panel's line. It stops short of the
   tab's sides, so they meet the line, and the first tab's meets the panel's
   corner. */
.Tabs_Tab-on::before,
.Tabs_Item > input:checked ~ .Tabs_Tab::before {
  content: '';
  position: absolute;
  inset: auto 2px calc(-1.5 * var(--room));
  height: calc(3 * var(--room));
  background: var(--card);
}
/* Only the checked radio's panel shows. Hiding the rest outranks a card's
   own display, wherever the card's rule comes. */
.Tabs_Item > input:not(:checked) ~ .Tabs_Panel {
  display: none;
}
.Tabs_Item > input:checked ~ .Tabs_Panel {
  display: grid;
}
.Tabs_Item > input:focus-visible ~ .Tabs_Tab {
  outline: 3px solid var(--accent);
  outline-offset: -5px;
}
/* Raised like a superscript; the shift is paint only, so the line keeps
   its height. */
.Tabs_Badge {
  position: relative;
  top: -0.5em;
  min-width: 1.1em;
  padding: 0 0.25em;
  border-radius: 1em;
  background: var(--accent);
  color: var(--bg);
  font-size: 0.65em;
  line-height: 1.5;
  font-variant-numeric: tabular-nums;
  text-align: center;
}

}
@layer components {
/* A glyph in lines: the words' height and a little more, sat on their
   baseline, stroked in their colour. */
.Icon {
  display: inline-block;
  width: 1.1em;
  height: 1.1em;
  flex: none;
  vertical-align: -.15em;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

}
@layer components {
/* Pencil's side navigation: a column of links beside an edge, the edge
   between this nav and the panel it leans against. The current link is a
   tab drawn in pencil and filled with the panel, and it covers the edge, so
   it opens into the panel, which is what makes it read as the page you are
   on. A nav with no panel beside it points --nav-edge and --nav-panel at
   nothing, and --nav-shut at graphite to close the tab's open side, so its
   current link is a pencil box (every nav on a phone, and any page's that
   says so). */
.SideNav {
  --nav-panel: var(--card);
  --nav-edge: var(--graphite);
  --nav-shut: transparent;
  position: relative;
  display: grid;
  gap: .4rem;
}
.SideNav::after {
  content: '';
  position: absolute;
  inset: 0 calc(-1 * var(--room)) 0 auto;
  width: calc(var(--stroke) + 2 * var(--room));
  background: linear-gradient(var(--nav-edge) 0 0) center / var(--stroke)
    100% no-repeat;
  filter: var(--drawn);
  pointer-events: none;
}
.SideNav_Link {
  position: relative;
  display: flex;
  align-items: center;
  gap: .65rem;
  padding: .6rem .8rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  color: var(--muted);
  font-size: .95rem;
  text-decoration: none;
  -webkit-user-select: none;
  user-select: none;
}
.SideNav_Link:hover,
.SideNav_Link-hover {
  color: var(--text);
}
.SideNav_Link-on {
  background: var(--nav-panel);
  color: var(--text);
  font-weight: 800;
  z-index: 1;
}
.SideNav_Link-on::after {
  content: '';
  position: absolute;
  inset: -1px 0 -1px -1px;
  border: var(--stroke) solid var(--graphite);
  border-right-color: var(--nav-shut);
  border-radius: var(--radius);
  filter: var(--drawn);
  pointer-events: none;
}
/* The gap the current tab opens in the edge. */
.SideNav_Link-on::before {
  content: '';
  position: absolute;
  inset: 2px calc(-1.5 * var(--room)) 2px auto;
  width: calc(3 * var(--room));
  background: var(--nav-panel);
}
/* A rule between groups of links, stopping short of the edge. */
.SideNav_Rule {
  height: calc(var(--stroke) + 2 * var(--room));
  margin: calc(1rem - var(--room)) .8rem;
  border: 0;
  background: var(--rule);
  filter: var(--drawn);
}
@media (max-width: 700px) {
  .SideNav {
    --nav-panel: transparent;
    --nav-edge: transparent;
    --nav-shut: var(--graphite);
    display: flex;
    flex-wrap: wrap;
  }
}

}
@layer components {
/* Pencil's box and radio are drawn, not the browser's: a graphite edge on
   the card, filled with the accent once checked, a tick or a dot in the
   paper's colour, as tall as a press beside it (--control-height). */
.Check {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  min-height: var(--control-height);
  line-height: 1.4;
  cursor: pointer;
}
.Check input {
  appearance: none;
  display: grid;
  place-content: center;
  box-sizing: border-box;
  width: 1.125rem;
  height: 1.125rem;
  flex: none;
  margin: 0;
  border: var(--stroke) solid var(--graphite);
  background: var(--card);
  cursor: inherit;
}
.Check input[type='radio'] {
  border-radius: 50%;
}
.Check input::before {
  content: '';
  width: .45rem;
  height: .45rem;
  transform: scale(0);
}
.Check input[type='checkbox']::before {
  width: .3rem;
  height: .6rem;
  margin-top: -.15rem;
  border: solid var(--bg);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg) scale(0);
}
.Check input[type='radio']::before {
  border-radius: 50%;
  background: var(--bg);
}
.Check input:checked {
  background: var(--accent);
  border-color: var(--accent);
}
.Check input:checked::before {
  transform: scale(1);
}
.Check input[type='checkbox']:checked::before {
  transform: rotate(45deg) scale(1);
}
.Check:has(input:disabled) {
  opacity: .55;
  cursor: not-allowed;
}
.Check input:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}

}
@layer components {
/* Things to browse, in groups. A group's heading is small, spaced capitals
   over a rule; an entry's title is large and ink, what it is muted under it,
   then what it shows. Entries stand well apart and groups further, so the
   eye finds each at a glance; a wide window gets a wider margin. The entry
   a link jumped to lights its title. */
.Catalog {
  display: grid;
  gap: calc(var(--gap) * 4);
  min-width: 0;
}
@media (min-width: 56rem) {
  .Catalog {
    padding: var(--gap) calc(var(--gap) * 2);
  }
}
.Catalog_Group {
  display: grid;
  gap: calc(var(--gap) * 2.5);
  min-width: 0;
  scroll-margin-top: var(--gap);
}
.Catalog_Heading {
  margin: 0;
  max-width: none;
  padding-bottom: var(--half-gap);
  border-bottom: 1px solid var(--border2);
  font-size: var(--small);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--heading);
}
.Catalog_Entry {
  display: grid;
  gap: 4px;
  min-width: 0;
  scroll-margin-top: var(--gap);
}
.Catalog_Title {
  margin: 0;
  font-size: var(--h3);
  font-weight: 600;
  line-height: 1.3;
  color: var(--text);
}
.Catalog_Entry:target > .Catalog_Title {
  color: var(--accent);
}
.Catalog_Sub {
  margin: 0 0 var(--gap);
  max-width: var(--measure);
  color: var(--muted);
}

}
@layer components {
/* Things side by side: as many figures to a line as fit, each as wide as
   what it shows asks, and no wider than the line. A figure is its caption,
   small and mono, over a stage: a raised panel with room all round, where
   what is shown sits as it would anywhere else. */
.Gallery {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap);
  min-width: 0;
}
.Gallery_Figure {
  flex: 0 1 max-content;
  min-width: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.Gallery_Caption {
  padding: 0 2px;
  font-family: var(--mono);
  font-size: var(--small);
  line-height: 1.4;
  color: var(--muted);
  overflow-wrap: anywhere;
}
.Gallery_Stage {
  flex: 1 1 auto;
  min-width: 0;
  /* Roomy, and less so on a phone, where the room is the line's. */
  padding: clamp(var(--gap), 4vw, calc(var(--gap) * 1.75));
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow-x: auto; /* what is wider than the line scrolls within its stage */
}

}

/* What every yaks.app page shares beside the kit (@yaks/ui, in _ui.css: the
   linen theme and the pencil skin, whose tokens draw yaks.app's lines): its
   face, Nunito, and the paints and measures its pages keep that are no
   theme's roles. */

/* Nunito, served from here so a first paint waits on no other site. One
   variable file per subset, and a page only fetches the subsets its text uses. */
@font-face {
  font-family: 'Nunito';
  font-weight: 400 800;
  font-display: swap;
  src: url(nunito-cyrillic-ext.88985ca614.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F,
    U+FE2E-FE2F;
}
@font-face {
  font-family: 'Nunito';
  font-weight: 400 800;
  font-display: swap;
  src: url(nunito-cyrillic.63b14e3ef0.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Nunito';
  font-weight: 400 800;
  font-display: swap;
  src: url(nunito-vietnamese.61e5958cf3.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169,
    U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323,
    U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'Nunito';
  font-weight: 400 800;
  font-display: swap;
  src: url(nunito-latin-ext.2c8d792869.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-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Nunito';
  font-weight: 400 800;
  font-display: swap;
  src: url(nunito-latin.ba344451ea.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;
}

@layer tokens {
  :root {
    /* Paints of yaks.app's own pages: the person's bubble and the
       assistant's, and the ground of an embedded app's preview, which
       matches the app in either scheme. */
    --mine: light-dark(#f8e0c8, #4e3b32); /* blush; ember */
    --theirs: light-dark(#e5eef5, #34404a); /* sky; dusk */
    --preview: #33493c; /* forest */

    /* Type, beside the theme's --size and --small. */
    --lead: 1.125rem;
    --fine: 0.875rem; /* what describes a thing: a hint, a status, a count */

    /* Space. The gaps derive from the theme's --gap, and the frame a page
       is drawn in — header to footer, style.css — is --measure and the four
       after it: a page kind re-points them on its own <body>, and a page
       that names no kind is one reading column with nothing beside it, its
       sections a rhythm apart so no two of them ever touch. */
    --wide-measure: 72rem; /* multi-column layouts */
    --side: 0px; /* a sidebar before the reading column */
    --aside: 0px; /* a gutter after it */
    --rhythm: 2rem; /* how far apart what fills the column sits */
    --quarter-gap: calc(var(--gap) / 4);
    --half-gap: calc(var(--gap) / 2);
    --wide-gap: calc(var(--gap) * 1.5);

    /* What floats over the page (an open menu, a chart's tip) is drawn at
       --float, above every raised part in the flow: a current tab, a
       selected tab, a chart. */
    --float: 10;
  }
@supports not (color: light-dark(#000, #fff)) {
:root {
  --mine: #f8e0c8;
  --theirs: #e5eef5;
}
@media (prefers-color-scheme: dark) {
:root {
  --mine: #4e3b32;
  --theirs: #34404a;
}
}
}
}


@layer base {
  * {
    box-sizing: border-box;
  }
  body {
    margin: 0;
    min-height: 100vh;
    display: grid;
    place-items: center;
    background: var(--bg);
    color: var(--text);
    font: 400 var(--size)/1.6 var(--font);
    -webkit-font-smoothing: antialiased;
  }
  main {
    width: 100%;
    max-width: 34rem;
    padding: 2rem 1rem;
    text-align: center;
    overflow-wrap: anywhere;
  }
  h1 {
    font-size: 1.6rem;
    font-weight: 800;
    line-height: 1.25;
    margin: 0 0 .5rem;
  }
  h2,
  h3 {
    line-height: 1.3;
  }
  p {
    color: var(--muted);
    margin: 0 0 1rem;
  }
  a {
    color: var(--accent);
    text-underline-offset: .18em;
  }
  :focus-visible {
    outline: 3px solid var(--accent);
    outline-offset: 3px;
  }
  form {
    display: grid;
    gap: .75rem;
    margin: 1.5rem 0 1rem;
  }
  form p {
    margin: 0;
    font-size: var(--small);
  }
  input {
    text-align: center;
  }
  code {
    font-family: var(--mono);
    font-size: .875em;
    background: var(--bg);
    padding: .1rem .35rem;
    overflow-wrap: anywhere;
  }
  /* The space selector and its rows are pressed, as a control is, not read. */
  .Desk_Space,
  .Desk_Row {
    -webkit-user-select: none;
    user-select: none;
  }
}

@layer sections {
  .Code {
    letter-spacing: .5em;
    font-size: 1.4rem;
    font-weight: 700;
  }
  .Again {
    margin-top: 0;
  }
  .Away {
    font-size: var(--small);
  }
  .Url code {
    display: inline-block;
    padding: .5rem 1rem;
    background: var(--card);
    font-size: var(--small);
  }
  main > .Card,
  main > .More {
    margin: 0 0 1rem;
    text-align: left;
  }
  .Card h2 {
    font-size: 1rem;
    font-weight: 800;
  }
  .Card ol {
    display: grid;
    gap: .4rem;
    margin: 0;
    padding-left: 1.2rem;
    color: var(--muted);
    font-size: var(--small);
  }
  .Card li::marker {
    color: var(--accent);
    font-weight: 700;
  }
  .Card pre {
    margin: 0;
    white-space: pre-wrap;
    font: inherit;
    color: var(--muted);
    text-align: left;
  }
  .Card form {
    margin: 0;
  }
  .Note {
    font-size: var(--fine);
    margin: .75rem 0 0;
  }
  .Card > .Note {
    margin: 0;
  }
  .Chips {
    justify-content: center;
    margin: 0 0 1.25rem;
  }
  .Files {
    display: grid;
    gap: .3rem;
    margin: 0;
    padding-left: 1.2rem;
    color: var(--muted);
    font-size: var(--small);
  }
  /* Each entry wraps within the column at any width: a grid track keeps no
     wider than its column, and nothing in it holds its line. */
  .Chat_Said {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: .45rem;
  }
  .Chat_Said > * {
    min-width: 0;
  }
  .Chat_Said:empty {
    display: none;
  }
  .Chat_Bubble {
    max-width: 90%;
    margin: 0;
    padding: .55rem .9rem;
    background: var(--bg);
    color: var(--text);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
  }
  .Chat_Bubble-you {
    justify-self: end;
    background: var(--accent);
    color: var(--bg);
  }
  .Chat_Bubble a {
    color: inherit;
  }
  .Chat_Tool {
    display: flex;
    gap: .4rem;
    align-items: baseline;
    margin: 0;
    padding: 0 .3rem;
    color: var(--muted);
    font-size: var(--fine);
  }
  .Chat_Tool-no {
    color: var(--negative);
  }
  .Chat_Name {
    font-weight: 700;
    min-width: 0;
    overflow-wrap: anywhere;
  }
  .Chat_Of {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .Chat_Note-no {
    color: var(--negative);
  }
  .Chat_Built {
    --pencil: var(--accent);
    margin: .4rem 0;
    padding: 1rem;
    background: var(--bg);
    text-align: center;
  }
  .Chat_Built p {
    margin: 0 0 .6rem;
  }
  .Chat_Note {
    margin: 0;
    color: var(--muted);
    font-size: var(--fine);
  }
  .Chat_Ask {
    margin: 0;
  }
  .Chat_Ask textarea {
    width: 100%;
    min-height: 4.5rem;
    resize: vertical;
  }
  .Chat_Ask textarea:disabled {
    opacity: .6;
  }
  .Fields {
    display: grid;
    gap: .55rem;
    margin: 0;
  }
  .Fields > div {
    display: grid;
    grid-template-columns: 6rem minmax(0, 1fr);
    align-items: center;
    gap: .65rem;
  }
  @media (max-width: 480px) {
    .Fields > div {
      grid-template-columns: minmax(0, 1fr);
      gap: .25rem;
    }
  }
  .Fields dt {
    color: var(--text);
    font-size: var(--small);
    font-weight: 700;
  }
  .Fields dd {
    min-width: 0;
    margin: 0;
  }
  .Connect_Icon {
    display: flex;
    align-items: center;
    gap: .65rem;
  }
  .Connect_Icon img {
    display: block;
    width: 56px;
    height: 56px;
    border: 1px solid var(--border);
  }
  .Connect_Setup {
    margin: 0 0 1.5rem;
    text-align: left;
  }
  .Connect_Path {
    margin: .25rem 0 0;
    font-size: var(--small);
    font-weight: 800;
  }
  .Connect_Next {
    display: grid;
    gap: .5rem;
    padding-top: .75rem;
    border-top: 1px solid var(--border);
  }
  .Connect_Next p {
    margin: 0;
    color: var(--text);
    font-weight: 800;
  }

  /* A person's invite (pages.ts `invitation`), shown to a friend on a phone:
     the code is what the page is for, so it is centred and as wide as the
     column allows, up to what a camera reads from across a table. */
  .Invite_Way {
    text-align: center;
  }
  .Invite_Lead {
    margin: 0 0 .75rem;
    color: var(--text);
    font-size: 1.2rem;
    font-weight: 800;
  }
  .Invite_Code {
    display: block;
    width: min(100%, 20rem);
    margin: 0 auto 1rem;
  }
  .Qr {
    display: block;
    width: 100%;
    height: auto;
    border-radius: var(--radius);
  }
  .Invite_Words {
    margin: 0 auto .75rem;
    max-width: 22rem;
    color: var(--text);
    font-weight: 700;
  }
  .Invite_Way .Note {
    max-width: 30rem;
    margin: 0 auto;
  }

  /* The dashboard's frame: the side with the brand and the tabs, and the body
     the current tab leans into. What fills the body is the style guide's cards,
     rows and forms (@yaks/ui, _ui.css); only what no other page draws is here.
     The frame fills the window, as the chat app's does, so the body's paper
     runs to the window's right edge; its content keeps its own width. */
  /* A TV (screen.ts): seen across a room, so the code is large; once
     paired, the draft fills the screen edge to edge, and each change it
     takes is said in a line over its corner. */
  .Tv main {
    max-width: 48rem;
  }
  .Tv_Code {
    margin: 1.5rem 0;
    color: var(--text);
    font: 700 clamp(2.5rem, 9vw, 6rem)/1 var(--mono);
    letter-spacing: .08em;
  }
  .Tv_Qr {
    display: block;
    width: min(60vw, 14rem);
    margin: 0 auto 1.5rem;
  }
  .Tv:has(.Tv_Frame) main {
    max-width: none;
    padding: 0;
  }
  .Tv_Frame {
    display: block;
    width: 100vw;
    height: 100vh;
    border: 0;
  }
  .Tv_Said {
    position: fixed;
    left: 2rem;
    bottom: 2rem;
    max-width: calc(100vw - 4rem);
    margin: 0;
    padding: .6rem 1.1rem;
    border: 1px solid var(--border2);
    border-radius: var(--radius);
    background: var(--card);
    color: var(--text);
    font-size: clamp(1.25rem, 2.5vw, 2rem);
  }
  .Tv_Said:empty {
    display: none;
  }
  .Desk {
    display: block;
  }
  .Desk main {
    display: grid;
    grid-template-columns: 15rem minmax(0, 1fr);
    align-items: start;
    max-width: none;
    min-height: 100vh;
    padding: 0;
    text-align: left;
  }
  .Desk_Side {
    position: sticky;
    top: 0;
    display: flex;
    flex-direction: column;
    gap: 2rem;
    z-index: 1;
    min-height: 100vh;
    padding: 2rem 1.25rem;
  }
  /* The edge between the side and the body, which the current tab opens. */
  .Desk_Side::after {
    content: '';
    position: absolute;
    inset: 0 calc(-1 * var(--room)) 0 auto;
    width: calc(var(--stroke) + 2 * var(--room));
    background: linear-gradient(var(--graphite) 0 0) center / var(--stroke)
      100% no-repeat;
    filter: var(--drawn);
    pointer-events: none;
  }
  .Desk_Brand {
    display: flex;
    align-items: center;
    gap: .65rem;
    color: var(--text);
    font-size: 1.25rem;
    font-weight: 800;
    text-decoration: none;
  }
  .Desk_Top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
  }
  .Desk_Close,
  .Desk_Bar {
    display: none;
  }
  /* The way back to the Operator's chat, over everything the side manages
     (pages.ts `navigation`). */
  .Desk_Back {
    gap: .4rem;
    min-width: 0;
  }
  .Desk_Title {
    margin: 0 .8rem;
    font-size: 1.25rem;
    font-weight: 800;
  }
  /* The side's two sections (pages.ts `navigation`): the space being
     managed, then the person's own, each under a small heading. */
  .Desk_Section {
    display: grid;
    gap: .4rem;
    min-width: 0;
  }
  .Desk_Group {
    margin: 0 .8rem;
    color: var(--muted);
    font-size: var(--fine);
    font-weight: 700;
  }
  /* The space and its pages on one sheet (pages.ts `navigation`), a shade
     behind the paper, running into the edge so the current tab still opens
     into the body. */
  .Desk_Here {
    display: grid;
    gap: .6rem;
    margin-right: -1.25rem;
    padding: .6rem 0 .6rem .5rem;
    border-radius: var(--radius) 0 0 var(--radius);
    background: var(--surface);
  }
  .Desk_Here > .Desk_Space,
  .Desk_Here > .Desk_Pick,
  .Desk_Here > .Desk_New {
    margin-right: 1.75rem;
  }
  /* A menu (`<details data-menu>`, public/menu.js) lies over the page while
     open. The menu itself is the layer, not its list: the list is positioned
     inside it, so whatever box the menu sits in, it paints at --float within
     that box's stacking context and over every raised sibling after it. */
  [data-menu] {
    position: relative;
  }
  [data-menu][open] {
    z-index: var(--float);
  }
  /* The space selector (pages.ts `chooser`): the space's name, and with
     another to go to, a button on its hatch, so it reads as something to
     press and not as the page you are on. Change opens the list over the
     page, wider than the side, drawn in pencil on a hatch the way a button
     sits on its. Change sits right of the name, and the name holds one
     line: whole where it fits, else cut with an ellipsis (its full text is
     the summary's title and the menu's row). A name that wraps in the
     column beside Change breaks every few letters (T-145350). */
  .Desk_Space {
    display: grid;
    grid-template-columns: 2rem minmax(0, 1fr);
    align-items: center;
    column-gap: .6rem;
    padding: .55rem .7rem;
    list-style: none;
  }
  .Desk_Pick > summary {
    grid-template-columns: 2rem minmax(0, 1fr) auto;
    position: relative;
    border-radius: var(--radius);
    background: var(--card);
    cursor: pointer;
  }
  .Desk_Pick > summary::before {
    content: '';
    position: absolute;
    inset: calc(var(--lift) - 1px) calc(-1px - var(--lift))
      calc(-1px - var(--lift)) calc(var(--lift) - 1px);
    border-radius: var(--radius);
    background: var(--hatch);
    clip-path: polygon(calc(100% - var(--lift)) 0, 100% 0, 100% 100%, 0 100%,
      0 calc(100% - var(--lift)), calc(100% - var(--lift))
      calc(100% - var(--lift)));
    pointer-events: none;
  }
  .Desk_Pick > summary::after {
    content: '';
    position: absolute;
    inset: -1px;
    border: var(--stroke) solid var(--graphite);
    border-radius: var(--radius);
    filter: var(--drawn);
    pointer-events: none;
  }
  .Desk_Pick > summary:hover {
    --lift: 5px;
    transform: translate(-1px, -1px);
  }
  .Desk_Pick[open] > summary {
    --lift: 1.5px;
    transform: translate(2.5px, 2.5px);
  }
  .Desk_Pick > summary::-webkit-details-marker {
    display: none;
  }
  .Desk_Tile {
    display: grid;
    place-items: center;
    width: 2rem;
    height: 2rem;
    border-radius: var(--radius);
    background: var(--accent);
    color: var(--bg);
    font-weight: 800;
  }
  img.Desk_Tile {
    object-fit: cover;
    background: none;
  }
  .Desk_Logo {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--gap);
  }
  .Desk_Logo .Desk_Tile {
    width: 4rem;
    height: 4rem;
    font-size: 1.75rem;
  }
  .Desk_Logo .Drop {
    flex: 1;
    min-width: 12rem;
  }
  .Desk_Name {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    min-width: 0;
    line-height: 1.25;
  }
  .Desk_Name b {
    overflow-wrap: anywhere;
  }
  .Desk_Space .Desk_Name > * {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
  }
  .Desk_Name small {
    color: var(--muted);
    font-size: var(--fine);
  }
  .Desk_Change {
    display: inline-flex;
    align-items: center;
    gap: .15rem;
    color: var(--accent);
    font-size: var(--fine);
    font-weight: 700;
  }
  .Desk_Pick[open] .Desk_Change {
    color: var(--muted);
  }
  .Desk_Menu {
    --lift: 6px;
    position: absolute;
    top: calc(100% + .6rem);
    left: 0;
    width: max-content;
    min-width: max(100%, 18rem);
    max-width: 26rem;
  }
  .Desk_Menu::before {
    content: '';
    position: absolute;
    inset: var(--lift) calc(-1 * var(--lift)) calc(-1 * var(--lift))
      var(--lift);
    border-radius: var(--radius);
    background: var(--hatch);
    clip-path: polygon(calc(100% - var(--lift)) 0, 100% 0, 100% 100%, 0 100%,
      0 calc(100% - var(--lift)), calc(100% - var(--lift))
      calc(100% - var(--lift)));
    filter: var(--drawn);
    pointer-events: none;
  }
  .Desk_Menu::after {
    content: '';
    position: absolute;
    inset: -1px;
    border: var(--stroke) solid var(--graphite);
    border-radius: var(--radius);
    filter: var(--drawn);
    pointer-events: none;
  }
  .Desk_List {
    position: relative;
    display: grid;
    max-height: min(34rem, 70vh);
    padding: .35rem 0;
    border-radius: var(--radius);
    background: var(--card);
    overflow-y: auto;
  }
  .Desk_Ask {
    margin: 0;
    padding: .5rem 1rem .6rem;
    color: var(--muted);
    font-size: var(--fine);
  }
  .Desk_Row {
    display: grid;
    grid-template-columns: 2rem minmax(0, 1fr) 1rem;
    align-items: center;
    gap: .75rem;
    margin: 0 .35rem;
    padding: .55rem .65rem;
    border-radius: var(--radius);
    color: var(--text);
    text-decoration: none;
  }
  .Desk_Row:hover {
    background: var(--well);
  }
  .Desk_Row[aria-current] {
    background: color-mix(in srgb, var(--card), var(--accent) 12%);
  }
  .Desk_Tick {
    color: var(--accent);
    font-weight: 800;
  }
  .Desk_New {
    padding: .5rem .7rem;
    color: var(--accent);
    font-size: var(--fine);
    font-weight: 700;
    text-decoration: none;
  }
  /* Under the rows, ruled off from them. */
  .Desk_List .Desk_New {
    position: relative;
    margin-top: .35rem;
    padding: .7rem 1rem .4rem;
  }
  .Desk_List .Desk_New::before {
    content: '';
    position: absolute;
    inset: calc(-1 * var(--room)) 0 auto;
    height: calc(var(--stroke) + 2 * var(--room));
    background: var(--rule);
    filter: var(--drawn);
  }
  /* The line over a page's title, naming the space it changes or "Your
     account". */
  .Desk_Whose {
    margin: 0;
    color: var(--muted);
    font-size: var(--fine);
  }
  .Desk_Out {
    padding: 0;
    border: 0;
    background: none;
    color: var(--link, var(--accent));
    font: inherit;
    text-align: left;
    text-decoration: underline;
    cursor: pointer;
  }
  .Desk_Danger .Card_Title {
    color: var(--negative);
  }
  .Desk_Count {
    margin-left: auto;
    font-size: var(--fine);
    opacity: .8;
  }
  .Desk_Foot {
    margin-top: auto;
    display: grid;
    gap: .5rem;
    padding: .5rem .8rem;
    font-size: var(--fine);
  }
  .Desk .SideNav {
    --nav-edge: transparent;
    margin-right: -1.25rem;
    gap: .15rem;
  }
  /* The links you are not on sit close; the current one keeps its room. */
  .Desk .SideNav_Link:not(.SideNav_Link-on),
  .Talk_Side .SideNav_Link:not(.SideNav_Link-on) {
    padding-block: .4rem;
  }
  .Desk .Desk_Here .SideNav {
    margin-right: 0;
  }
  /* The body keeps what it raises (a selected tab, a chart) to itself, so
     the side, and a menu opened from it over the body, lies above it all. */
  .Desk_Body {
    isolation: isolate;
    min-width: 0;
    min-height: 100vh;
    background: var(--card);
    padding: 2rem clamp(1.25rem, 4vw, 3rem) 3rem;
  }
  .Desk_Head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    max-width: 52rem;
    margin-bottom: 1.5rem;
  }
  .Desk_Head h1 {
    font-size: 1.75rem;
    line-height: 1.2;
    margin: .15rem 0 0;
  }
  .Desk_Period {
    margin: .25rem 0 0;
    font-size: var(--small);
  }
  .Desk_Address {
    font-size: var(--fine);
    text-decoration: none;
    color: var(--muted);
  }
  .Desk_Head .Button {
    flex: none;
  }
  .Desk_Content {
    display: grid;
    gap: var(--gap);
    max-width: 52rem;
    font-size: var(--small);
  }
  .Desk_Content > * {
    margin: 0;
  }
  .Desk input,
  .Desk textarea,
  .Card input,
  .Card textarea {
    text-align: left;
  }
  .Desk form > .Button {
    justify-self: start;
  }
  .Desk_Connect {
    border-color: var(--accent);
  }
  .Apps {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
    gap: var(--gap);
  }
  .Apps_Item {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: start;
    gap: .35rem;
    min-width: 0;
    min-height: 10.5rem;
    padding: 1rem 1.1rem;
    color: var(--text);
    overflow-wrap: anywhere;
  }
  .Apps_Item:hover {
    --pencil: var(--accent);
  }
  .Apps_Item img {
    width: 40px;
    height: 40px;
    margin-bottom: .4rem;
  }
  .Apps_Item strong {
    font-size: 1rem;
    line-height: 1.3;
  }
  .Apps_Open {
    color: inherit;
    text-decoration: none;
  }
  .Apps_Open::after {
    content: '';
    position: absolute;
    inset: 0;
  }
  .Apps_Open:focus-visible {
    outline: 0;
  }
  .Apps_Open:focus-visible::after {
    outline: 3px solid var(--accent);
    outline-offset: 3px;
  }
  .Apps_Path {
    color: var(--muted);
    font-size: var(--fine);
  }
  .Apps_Tags {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    margin-top: auto;
    padding-top: .5rem;
    color: var(--muted);
    font-size: var(--fine);
    line-height: 1.4;
  }
  .Apps_Tag {
    padding: .05rem .45rem;
    background: var(--bg);
  }
  .Apps.Apps-one {
    grid-template-columns: minmax(0, 18rem);
    justify-content: center;
    margin: 1.5rem 0 0;
    text-align: left;
  }
  .Apps-one .Apps_Item {
    min-height: 0;
  }
  .Apps_Tags:empty {
    display: none;
  }
  .Apps_Tag-warn {
    position: relative;
    background: color-mix(in srgb, var(--negative) 12%, var(--card));
    color: var(--negative);
    font-weight: 700;
    text-decoration: none;
  }
  .Apps_Tag-link {
    position: relative;
    color: var(--text);
  }
  .Data main {
    max-width: 44rem;
    text-align: left;
  }
  .Data main > .Card {
    margin-bottom: 1rem;
  }
  .Data main .Card > .Field {
    margin-bottom: .75rem;
  }
  .Data main img {
    max-width: 6rem;
    max-height: 6rem;
  }
  .Fix_Said {
    color: var(--text);
    font-family: var(--mono);
    font-size: var(--fine);
    overflow-wrap: anywhere;
  }
  .Desk_More {
    display: flex;
    flex-wrap: wrap;
    gap: .25rem 1rem;
    margin: 0;
  }
  .Desk_Options {
    display: grid;
    gap: var(--gap);
    align-items: start;
  }
  @media (min-width: 1100px) {
    .Desk_Options {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }
  }
  .Desk_Skip {
    position: absolute;
    top: -5rem;
    left: 1rem;
    padding: .6rem 1rem;
    background: var(--card);
    z-index: 1;
  }
  .Desk_Skip:focus {
    top: 1rem;
  }
  @media (max-width: 700px) {
    .Desk main {
      display: block;
    }
    /* The top bar: Menu, and the page with the space it is in. */
    .Desk_Bar {
      position: sticky;
      top: 0;
      z-index: 2;
      display: flex;
      align-items: center;
      gap: .75rem;
      padding: .6rem 1rem;
      background: var(--bg);
      border-bottom: 1px solid var(--border2);
    }
    .Desk_Where {
      display: grid;
      min-width: 0;
      line-height: 1.2;
    }
    .Desk_Where small {
      color: var(--muted);
      font-size: var(--fine);
      overflow-wrap: anywhere;
    }
    /* The same side, behind Menu: the whole screen while it is open. */
    .Desk_Side {
      display: none;
    }
    .Desk_Side:target {
      position: fixed;
      inset: 0;
      z-index: 3;
      display: flex;
      gap: 1.25rem;
      min-height: 0;
      padding: 1rem;
      overflow: hidden auto;
      background: var(--bg);
    }
    .Desk_Side::after {
      display: none;
    }
    .Desk_Menu {
      position: relative;
      top: auto;
      margin: .6rem var(--lift) var(--lift) 0;
      width: auto;
      min-width: 0;
      max-width: none;
    }
    .Desk_List {
      max-height: none;
    }
    .Desk_Close {
      display: inline-flex;
    }
    .Desk_Brand {
      font-size: 1.1rem;
    }
    .Desk_Brand img {
      width: 36px;
      height: 36px;
    }
    .Desk .SideNav {
      margin-right: 0;
      gap: .4rem;
    }
    .Desk .SideNav_Link:not(.SideNav_Link-on) {
      padding-block: .6rem;
    }
    .Desk_Here {
      margin-right: 0;
      padding: .6rem .5rem;
      border-radius: var(--radius);
    }
    .Desk_Here > .Desk_Space,
    .Desk_Here > .Desk_Pick,
    .Desk_Here > .Desk_New {
      margin-right: var(--lift);
    }
    .Desk_Body {
      min-height: 0;
      padding: 1.5rem 1rem 2.5rem;
    }
    .Desk_Head {
      margin-bottom: 1.25rem;
    }
    .Desk_Head h1 {
      font-size: 1.5rem;
    }
    .Apps {
      grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
      gap: .75rem;
    }
    .Apps_Item {
      min-height: 10rem;
      padding: .9rem;
    }
  }

  /* The agents a person connected, as rows (connected_ui.ts), or the ones
     with a web home as a line of links to open them. */
  .Agents-links {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem 1.5rem;
    margin: 0;
    padding: 0;
    list-style: none;
  }
  .Agents_Open {
    display: inline-flex;
    align-items: center;
    gap: var(--quarter-gap);
    color: var(--accent);
    font-size: var(--small);
    font-weight: 700;
    text-underline-offset: .18em;
    white-space: nowrap;
  }

  /* An invitation not yet taken, in a person's row (render/held.ts). */
  .People_Waiting {
    color: var(--negative);
  }

  /* The admin's directory (admin.ts): a search bar, and one card of rows with
     hairlines between them, as the style guide draws .Rows, each saying what
     it uses, each figure under the word for it; one column on a phone. */
  .Directory_Bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .75rem 1.5rem;
    margin: 0 0 1.5rem;
  }
  .Directory_Find {
    display: flex;
    gap: .5rem;
    flex: 1 1 20rem;
    max-width: 30rem;
    margin: 0;
  }
  .Directory_Find .Field {
    flex: 1;
  }
  .Directory_Bar > a {
    font-size: .9rem;
  }
  /* A card of rows edge to edge, a hairline between each. Each row sits in
     its own <li>, and the end rows round off with the card. */
  .Directory {
    display: grid;
    gap: 0;
    margin: 0;
    padding: 0;
    list-style: none;
  }
  .Directory > li + li {
    border-top: 1px solid var(--border);
  }
  .Directory > li:first-child > .Directory_Row {
    border-top-left-radius: var(--radius);
    border-top-right-radius: var(--radius);
  }
  .Directory > li:last-child > .Directory_Row {
    border-bottom-left-radius: var(--radius);
    border-bottom-right-radius: var(--radius);
  }
  .Directory_Row {
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 2fr);
    align-items: center;
    gap: .5rem 1.5rem;
    padding: .85rem 1.25rem;
  }
  .Directory_Row:hover {
    background: color-mix(in srgb, var(--bg), var(--card) 55%);
  }
  .Directory_Who {
    display: grid;
    gap: .1rem;
    min-width: 0;
  }
  .Directory_Who .Apps_Tags {
    margin: .25rem 0 0;
    padding: 0;
  }
  .Directory_Open {
    color: var(--text);
    text-decoration: none;
    overflow-wrap: anywhere;
  }
  .Directory_Open::after {
    content: '';
    position: absolute;
    inset: 0;
  }
  .Directory_Open:focus-visible {
    outline: 0;
  }
  .Directory_Open:focus-visible::after {
    outline: 3px solid var(--accent);
    outline-offset: 3px;
  }
  .Directory_Sub {
    color: var(--muted);
    font-size: .85rem;
    overflow-wrap: anywhere;
  }
  .Directory_Uses {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: .5rem 1rem;
    margin: 0;
  }
  .Directory_Uses dt {
    color: var(--muted);
    font-size: .8rem;
  }
  .Directory_Uses dd {
    margin: 0;
    font-variant-numeric: tabular-nums;
  }
  .Directory_Facts > div {
    grid-template-columns: 10rem minmax(0, 1fr);
  }
  .Directory_Facts dt {
    font-weight: 700;
    color: var(--muted);
  }
  .Directory_Content .Group {
    margin-top: 2rem;
  }
  @media (max-width: 700px) {
    .Directory_Row {
      grid-template-columns: minmax(0, 1fr);
    }
    .Directory_Uses {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }
    .Directory_Facts > div {
      grid-template-columns: 8rem minmax(0, 1fr);
    }
  }
  /* The Operator's chat app (operator-page.ts `chatPage`): the product's
     side, and one conversation filling the page, read down a column with the
     box to write in held at the foot of the window. The page itself scrolls;
     the side holds the window's height, and what lies between its top and
     Manage scrolls on its own when it is longer (`.Talk_Scroll`). */
  .Talk_Page {
    display: block;
  }
  .Talk_Page main {
    max-width: none;
    padding: 0;
    text-align: left;
  }
  .Talk {
    display: grid;
    grid-template-columns: 17rem minmax(0, 1fr);
    min-height: 100dvh;
  }
  .Talk_Side {
    position: sticky;
    top: 0;
    display: flex;
    flex-direction: column;
    gap: .75rem;
    height: 100dvh;
    padding: 1rem .75rem;
    background: var(--surface);
  }
  /* The edge between the side and the conversation, drawn inside the side so
     the current tab, which is clipped where the side scrolls, still covers
     it and opens into the page (@yaks/ui `SideNav`). */
  .Talk_Side::after {
    content: '';
    position: absolute;
    inset: 0 0 0 auto;
    width: calc(var(--stroke) + 2 * var(--room));
    background: linear-gradient(var(--graphite) 0 0) center / var(--stroke)
      100% no-repeat;
    filter: var(--drawn);
    pointer-events: none;
  }
  /* The region scrolls down only. Its padding is the room the selector's
     hatch and lift take on hover, so the clip at its edge never cuts them;
     the current tab still reaches over the side's edge and is cut there. */
  .Talk_Scroll {
    --reach: calc(var(--stroke) + 6px);
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: .75rem;
    min-height: 0;
    margin: calc(-1 * var(--reach)) -.75rem calc(-1 * var(--reach))
      calc(-1 * var(--reach));
    padding: var(--reach) .75rem var(--reach) var(--reach);
    overflow: hidden auto;
  }
  /* The side's places are the settings' tabs (pages.ts `navigation`): the
     current one opens into the page beside it. */
  .Talk_Side .SideNav {
    --nav-edge: transparent;
    --nav-panel: var(--bg);
    flex: none;
    margin-right: -.75rem;
    gap: .15rem;
  }
  .Talk_Top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    padding: 0 .4rem;
  }
  .Talk_Brand {
    display: flex;
    align-items: center;
    gap: .55rem;
    color: var(--text);
    font-weight: 800;
    text-decoration: none;
  }
  /* Whose Operator this is (operator-page.ts `side`): the space, in the
     dashboard's selector, whose list stays inside the side it scrolls in. */
  .Talk_Whose {
    display: grid;
  }
  .Talk_Whose .Desk_Menu {
    min-width: 100%;
    max-width: 100%;
  }
  .Talk_Icon {
    flex: none;
    width: 1.5rem;
    height: 1.5rem;
    border-radius: .35rem;
    object-fit: cover;
  }
  .Talk_Side .SideNav_Link.Talk_All {
    color: var(--muted);
    font-size: var(--fine);
  }
  .Talk_Count {
    min-width: 1.3rem;
    margin-left: auto;
    padding: 0 .35rem;
    border-radius: 99px;
    background: var(--negative);
    color: var(--card);
    font-size: var(--fine);
    font-weight: 800;
    text-align: center;
  }
  /* What each part of the side holds, said small over it. */
  .Talk_Group {
    margin: .25rem .6rem -.5rem;
    color: var(--muted);
    font-size: var(--fine);
    font-weight: 800;
  }
  .Talk_None {
    margin: 0 .6rem;
  }
  .Talk_None {
    color: var(--muted);
    font-size: var(--fine);
  }
  .Talk_Side .Talk_Foot {
    padding-top: .5rem;
    border-top: 1px solid var(--border2);
  }
  .Talk_Close,
  .Talk_Menu,
  .Talk_Back,
  .Talk_Show {
    display: none;
  }
  /* The bar's button to the app, named for it: a button is one line tall,
     so a long name is cut short rather than wrapped out of it on a phone. */
  .Talk_Show {
    min-width: 0;
    max-width: 50%;
  }
  .Talk_ShowName {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .Talk_Main {
    display: flex;
    flex-direction: column;
    min-width: 0;
    min-height: 100dvh;
  }
  .Talk_Bar {
    position: sticky;
    top: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .75rem 1.25rem;
    background: var(--bg);
    border-bottom: 1px solid var(--border2);
  }
  .Talk_Heads {
    display: grid;
    min-width: 0;
  }
  .Talk_Who {
    margin: 0;
    color: var(--muted);
    font-size: var(--fine);
  }
  .Talk_Head {
    min-width: 0;
    margin: 0;
    overflow: hidden;
    font-size: 1rem;
    font-weight: 700;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  /* The conversation, at a reading width in the middle of the page. */
  .Talk_Column,
  .Talk_Keep,
  .Talk_Needs,
  .Talk_Box,
  .Talk_Starts {
    width: 100%;
    max-width: 46rem;
    margin: 0 auto;
    padding-inline: 1.25rem;
  }
  .Talk_Column {
    flex: 1;
    padding-block: 1.5rem 2rem;
  }
  .Talk_Hello {
    padding-top: 18vh;
    text-align: center;
  }
  .Talk_Hello h2 {
    margin: 0 0 .5rem;
    font-size: 1.5rem;
  }
  /* The yak beside the box (operator-page.ts `composer`), taking no room
     from the conversation: in the margin to its left where the page is wide
     enough, else sitting on its top edge. */
  .Talk_Main {
    container: talk / inline-size;
  }
  .Talk_Write {
    position: relative;
  }
  .Talk_Yak {
    position: absolute;
    bottom: calc(100% - .2rem);
    left: .75rem;
    width: 2.5rem;
    height: 2.5rem;
    object-fit: contain;
    pointer-events: none;
  }
  @container talk (min-width: 54rem) {
    .Talk_Yak {
      right: calc(100% + .75rem);
      bottom: 0;
      left: auto;
      width: 4rem;
      height: 4rem;
    }
  }
  /* A new chat (operator-page.ts `chatPage`): the greeting, what needs the
     person, the box and the ways to start, held together in the middle of
     the window. */
  .Talk_Main-new .Talk_Column {
    flex: none;
    margin-top: auto;
    padding-bottom: 1rem;
  }
  .Talk_Main-new .Talk_Hello {
    padding-top: 0;
  }
  .Talk_Main-new .Talk_Box {
    position: static;
    padding-bottom: .75rem;
    background: none;
  }
  .Talk_Needs {
    margin-bottom: .75rem;
  }
  /* A newcomer's address, asked for over the chat (newcomer.ts). */
  .Talk_Keep {
    display: grid;
    gap: .75rem;
    padding-block: 1rem .25rem;
  }
  .Talk_Needs:empty {
    display: none;
  }
  /* Updates from the Operator (updates.ts): a card for each, what needs the
     person first, then what happened, newest first. */
  .Updates {
    display: grid;
    align-content: start;
    gap: .75rem;
  }
  .Update_Words {
    font-size: 1.0625rem;
  }
  .Update_Meta,
  .Update_When,
  .Update_Choices {
    color: var(--muted);
    font-size: var(--fine);
  }
  .Update-needs .Update_When {
    margin-left: auto;
  }
  .Update_Choices {
    padding-left: 1.25rem;
  }
  .Update_Reply > summary {
    color: var(--muted);
    font-size: var(--fine);
    cursor: pointer;
  }
  .Update_Reply .Update_Form {
    display: grid;
    gap: .5rem;
    margin-top: .5rem;
    justify-items: end;
  }
  .Update_Reply textarea {
    width: 100%;
  }
  .Talk_Starts {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: .5rem;
    margin-bottom: auto;
    padding-bottom: 2rem;
  }
  /* An app open beside the chat (operator-page.ts `canvas`): a third column
     the height of the window, held in place while the chat scrolls, the app
     itself filling it under its name. */
  .Talk-app {
    grid-template-columns: 17rem minmax(20rem, 1fr) minmax(0, 1.4fr);
  }
  .Talk_App {
    position: sticky;
    top: 0;
    display: grid;
    grid-template-rows: auto minmax(0, 1fr);
    height: 100dvh;
    border-left: 1px solid var(--border2);
    background: var(--surface);
  }
  .Talk_AppHead {
    display: flex;
    align-items: center;
    gap: .6rem;
    min-width: 0;
    padding: .6rem 1rem;
  }
  .Talk_AppName {
    display: grid;
    min-width: 0;
    margin-right: auto;
    line-height: 1.25;
  }
  .Talk_AppName b,
  .Talk_AppName small {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .Talk_AppName small {
    color: var(--muted);
    font-size: var(--fine);
  }
  .Talk_Stage {
    min-height: 0;
    padding: 0 1rem 1rem;
  }
  .Talk_Frame {
    display: block;
    width: 100%;
    height: 100%;
    border: 0;
    border-radius: .75rem;
    background: var(--card);
    box-shadow: 0 0 0 1px var(--border2);
  }
  /* What it is made of, a tab each over one sheet that fills the column
     under its name: the lists scroll inside the sheet, whose drawn edge
     stays put, and its screens fill it. */
  .Talk_Made {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-template-rows: auto minmax(0, 1fr);
    height: 100%;
  }
  .Talk_Made .Tabs_Panel {
    grid-column: 1 / -1;
    grid-row: 2;
    grid-template-rows: minmax(0, 1fr);
    align-content: stretch;
  }
  /* Room inside the scroller for the pencil lines of what it holds. */
  .Talk_Sheet {
    display: grid;
    align-content: start;
    gap: .75rem;
    min-height: 0;
    margin: -.25rem;
    padding: .25rem;
    overflow: auto;
  }
  .Talk_Part-screens {
    --pad-block: .5rem;
    --pad-inline: .5rem;
  }
  .Talk_Part-screens .Talk_Sheet {
    display: flex;
    flex-direction: column;
    gap: .5rem;
    overflow: visible;
  }
  .Talk_Part-screens .Empty {
    margin: auto 0;
  }
  .Talk_Part-screens .Talk_Frame {
    flex: 1 1 auto;
    min-height: 0;
    box-shadow: none;
    border-radius: calc(var(--radius) - .25rem);
  }
  .Talk_MadeNote {
    margin: 0;
    color: var(--muted);
    font-size: var(--fine);
  }
  .Talk_Part-screens .Talk_MadeNote {
    padding: .25rem .5rem 0;
  }
  /* The draft or the app live, a radio each, while both are there: only
     the checked one's note and frame show. */
  .Talk_Screens {
    --control-height: 2rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0 1.25rem;
    padding: 0 .5rem;
  }
  .Talk_Screens ~ .Talk_MadeNote {
    padding-top: 0;
  }
  .Talk_Part-screens:has([name=screen]) [data-screen] {
    display: none;
  }
  .Talk_Part-screens:has([name=screen][value=draft]:checked) [data-screen=draft],
  .Talk_Part-screens:has([name=screen][value=live]:checked) [data-screen=live] {
    display: block;
  }
  .Talk_Thread,
  .Talk_Said {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
  }
  .Talk_Said > * {
    min-width: 0;
  }
  /* The person's words sit to the right in a bubble; the Operator's replies
     are the page's own text. */
  .Talk_You {
    justify-self: end;
    max-width: 85%;
    margin: 0;
    padding: .6rem 1rem;
    border-radius: 1.1rem;
    background: var(--mine);
    color: var(--text);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
  }
  /* The channel the words came by, a small mark before them. */
  .Talk_Via {
    margin-right: .4em;
    color: var(--muted);
  }
  .Talk_Via .Icon {
    width: .95em;
    height: .95em;
    vertical-align: -.1em;
  }
  .Talk_Said > div:has(> .Talk_You) {
    display: grid;
  }
  /* When each message was sent, quiet under it: the person's to the right. */
  .Talk_When {
    display: block;
    margin-top: .25rem;
    color: var(--muted);
    font-size: var(--fine);
  }
  .Talk_Said > div:has(> .Talk_You, > .Talk_Files) > .Talk_When {
    justify-self: end;
  }
  .Talk_Reply {
    margin: 0;
    color: var(--text);
    overflow-wrap: anywhere;
  }
  .Talk_Reply p,
  .Talk_Reply ul,
  .Talk_Reply ol,
  .Talk_Written :is(p, ul, ol, h1, h2, h3, h4) {
    margin: 0 0 .75rem;
    color: inherit;
  }
  .Talk_Reply > :last-child,
  .Talk_Reply .Body > :last-child,
  .Update_Words .Body > :last-child,
  .Talk_Written > :last-child {
    margin-bottom: 0;
  }
  .Talk_Reply pre,
  .Talk_Written pre {
    padding: .6rem .8rem;
    background: var(--card);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
  }
  .Talk_Reply table {
    display: block;
    max-width: 100%;
    overflow-x: auto;
  }
  /* A step the Operator took, as one quiet line that opens on what it asked
     for and what came back. */
  .Talk_Step > summary {
    display: inline-flex;
    gap: .4rem;
    align-items: baseline;
    color: var(--muted);
    font-size: var(--small);
    cursor: pointer;
    list-style: none;
  }
  .Talk_Step > summary::-webkit-details-marker {
    display: none;
  }
  .Talk_Step > summary::after {
    content: '›';
    transition: transform .15s;
  }
  .Talk_Step[open] > summary::after {
    transform: rotate(90deg);
  }
  .Talk_Step-on > summary {
    color: var(--accent);
  }
  .Talk_Step-no > summary {
    color: var(--negative);
  }
  .Talk_Detail {
    margin: .4rem 0 0;
    padding: .6rem .8rem;
    border-left: 2px solid var(--border2);
    font-size: var(--small);
  }
  .Talk_Detail > p {
    margin: .4rem 0 .2rem;
    font-weight: 700;
  }
  .Talk_Detail > p:first-child {
    margin-top: 0;
  }
  .Talk_Detail > span {
    display: block;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
  }
  .Talk_Facts {
    display: grid;
    gap: .2rem;
    margin: 0;
  }
  .Talk_Facts > div {
    display: grid;
    grid-template-columns: minmax(0, 9rem) minmax(0, 1fr);
    gap: .6rem;
  }
  .Talk_Facts dt {
    color: var(--muted);
  }
  .Talk_Facts dd {
    margin: 0;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
  }
  .Talk_Facts .Talk_Facts > div {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }
  .Talk_Note {
    margin: 0;
    color: var(--muted);
    font-size: var(--small);
  }
  .Talk_Note-no {
    color: var(--negative);
  }
  /* An error: a sentence in words, and what it said only when opened. */
  .Talk_Trouble > details > summary {
    color: var(--muted);
    font-size: var(--small);
    cursor: pointer;
  }
  .Talk_Trouble pre {
    margin: .4rem 0 0;
    padding: .6rem .8rem;
    background: var(--card);
    font-size: var(--small);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
  }
  /* What a call's talking model asked the Operator, behind a small mark
     between what the caller said and what they heard. */
  .Talk_Asked > summary {
    display: inline-flex;
    color: var(--muted);
    cursor: pointer;
    list-style: none;
  }
  .Talk_Asked > summary::-webkit-details-marker {
    display: none;
  }
  .Talk_Asked > summary .Icon {
    width: 1em;
    height: 1em;
  }
  .Talk_Inner {
    display: flex;
    flex-direction: column;
    gap: .6rem;
    margin: .4rem 0 0;
    padding: .6rem .8rem;
    border-left: 2px solid var(--border2);
  }
  /* What a model was told (a system prompt, a persona), set apart in a dashed
     frame, closed until opened. */
  .Talk_Told {
    padding: .4rem .8rem;
    border: 1px dashed var(--border2);
    border-radius: .6rem;
    font-size: var(--small);
  }
  .Talk_Told > summary {
    color: var(--muted);
    cursor: pointer;
  }
  .Talk_Written {
    max-height: 60vh;
    margin: .4rem 0 0;
    overflow: auto;
    overflow-wrap: anywhere;
  }
  .Talk_Told pre {
    max-height: 60vh;
    margin: .4rem 0 0;
    overflow: auto;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
  }
  /* What the Operator is doing now, in words a screen reader hears; the yak
     beside the box shows it. */
  .Talk_Now {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  /* The files a person sent, under their words at the right: a picture as
     itself, any other file as a chip with its kind and name. */
  .Talk_Files {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    margin: 0;
    font-size: var(--small);
  }
  .Talk_Files a {
    overflow-wrap: anywhere;
  }
  .Talk_Said .Talk_Files {
    justify-self: end;
    justify-content: flex-end;
    max-width: 85%;
  }
  .Talk_Said > div:has(> .Talk_Files) {
    display: grid;
    gap: .5rem;
  }
  .Talk_Picture img {
    display: block;
    width: auto;
    max-width: min(100%, 16rem);
    max-height: 12rem;
    border-radius: .75rem;
    object-fit: cover;
  }
  .Talk_File {
    display: flex;
    align-items: center;
    gap: .5rem;
    max-width: 16rem;
    padding: .35rem .75rem .35rem .35rem;
    border-radius: .75rem;
    background: var(--mine);
    color: var(--text);
    text-decoration: none;
  }
  /* The box to write in, held at the foot of the window. */
  .Talk_Box {
    position: sticky;
    bottom: 0;
    z-index: 1;
    margin-top: 0;
    padding-block: .5rem 1rem;
    background: linear-gradient(transparent, var(--bg) 1rem);
  }
  .Talk_Write {
    display: grid;
    gap: .5rem;
    padding: .5rem;
    border: 1px solid var(--border2);
    border-radius: 1rem;
    background: var(--card);
  }
  .Talk_Field {
    width: 100%;
    min-height: calc(var(--control-height) * 1.5);
    max-height: 40vh;
    resize: none;
  }
  .Talk_Tools {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
  }
  .Talk_Attach {
    position: relative;
    color: var(--muted);
    font-size: var(--small);
    cursor: pointer;
  }
  .Talk_Attach:hover {
    color: var(--text);
  }
  .Talk_Attach input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
  }
  .Talk_Attach:focus-within {
    outline: 3px solid var(--accent);
    outline-offset: 3px;
  }
  .Talk_Tools .Drop_Said {
    flex: 1;
    min-width: 0;
    overflow-wrap: anywhere;
  }
  .Talk_Stop,
  .Talk_Send {
    margin-left: auto;
  }
  .Talk_Stop {
    display: none;
  }
  .Talk:has([data-task][data-pending]) .Talk_Stop {
    display: inline-flex;
  }
  .Talk:has([data-task][data-pending]) .Talk_Send {
    margin-left: 0;
  }
  /* The microphone (public/voice.js): a calm glow while it listens. */
  .Talk_Voice[hidden] {
    display: none;
  }
  .Talk_Voice[data-listening] {
    color: var(--accent);
    border-color: var(--accent);
    box-shadow: 0 0 0 .25rem color-mix(in srgb, var(--accent) 18%, transparent);
    animation: Talk_Listening 1.6s ease-in-out infinite alternate;
  }
  @keyframes Talk_Listening {
    to {
      box-shadow: 0 0 0 .45rem color-mix(in srgb, var(--accent) 8%,
        transparent);
    }
  }
  @media (prefers-reduced-motion: reduce) {
    .Talk_Voice[data-listening] {
      animation: none;
    }
  }
  .Talk_Status {
    margin: .3rem 0 0;
    color: var(--muted);
    font-size: var(--fine);
  }
  .Talk_Status:empty {
    display: none;
  }
  @media (max-width: 700px) {
    .Talk {
      display: block;
    }
    .Talk_Menu {
      display: inline-flex;
    }
    .Talk_Bar {
      padding: .5rem 1rem;
    }
    .Talk_Column,
    .Talk_Box {
      padding-inline: 1rem;
    }
    .Talk_Hello {
      padding-top: 10vh;
    }
    /* The same side, behind the bar's button: the whole screen while it is
       open. */
    .Talk_Side {
      display: none;
    }
    .Talk_Side:target {
      position: fixed;
      inset: 0;
      z-index: 3;
      display: flex;
      height: auto;
    }
    .Talk_Side::after {
      content: none;
    }
    .Talk_Side .SideNav {
      margin-right: 0;
      gap: .4rem;
    }
    .Talk_Side .SideNav_Link:not(.SideNav_Link-on) {
      padding-block: .6rem;
    }
    .Talk_Close {
      display: inline-flex;
    }
    /* The app takes the screen in the chat's place while chosen from the
       bar (`#app`), and Chat goes back. */
    .Talk-app .Talk_Show {
      display: inline-flex;
      margin-left: auto;
    }
    .Talk_App {
      display: none;
    }
    .Talk_App:target {
      position: fixed;
      inset: 0;
      z-index: 3;
      display: grid;
      height: auto;
      border: 0;
    }
    .Talk_Back {
      display: inline-flex;
    }
    .Talk_Stage {
      padding: 0 .5rem .5rem;
    }
    .Talk_Facts > div {
      grid-template-columns: minmax(0, 1fr);
      gap: 0;
    }
  }
}
