/* Domlings: the E-ink look of Slate, dark or light (theme.js picks, as the device has
   it unless chosen under Настройки). Pure white on black or black on white (no greys,
   colours, shadows or transitions), Lato, dotted rules between rows. */

@font-face { font-family: "Lato"; src: url("fonts/lato_regular.ttf") format("truetype"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Lato"; src: url("fonts/lato_bold.ttf") format("truetype"); font-weight: 700; font-display: swap; }
/* Lato here has no Cyrillic. Carlito is drawn from Lato and has it, so it stands in
   for those letters only, scaled up because it runs smaller. */
@font-face { font-family: "Lato"; src: url("fonts/carlito_regular.ttf") format("truetype"); font-weight: 400; font-display: swap; size-adjust: 110%; unicode-range: U+0400-04FF, U+2116; }
@font-face { font-family: "Lato"; src: url("fonts/carlito_bold.ttf") format("truetype"); font-weight: 700; font-display: swap; size-adjust: 110%; unicode-range: U+0400-04FF, U+2116; }

:root {
  --ink: #ffffff;
  --paper: #000000;
  --spirit-body: #ffffff;
  --spirit-mark: #000000;
  --spirit-edge: transparent;
  --gutter: max(16px, env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px));
  color-scheme: dark;
}
:root[data-theme="light"] { --ink: #000000; --paper: #ffffff; --spirit-edge: #000000; color-scheme: light; }
/* The house icon is drawn white on black, so in the light it's turned over too. */
:root[data-theme="light"] img[src$="icon.svg"] { filter: invert(1); }
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body { margin: 0; background: var(--paper); color: var(--ink); font: 17px/1.45 "Lato", system-ui, sans-serif;
  -webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent; }
button, input, textarea, select { font: inherit; color: var(--ink); }
input, textarea, select { font-weight: 400; }
button { background: none; border: 0; padding: 0; cursor: pointer; }
a { color: var(--ink); }
/* No greys, so a slant tells a hint from a value. */
::placeholder { color: var(--ink); opacity: 1; font-style: italic; }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
input:-webkit-autofill { -webkit-text-fill-color: var(--ink); caret-color: var(--ink); box-shadow: inset 0 0 0 100px var(--paper); }
h1, h2, p { margin: 0; }

/* On a desktop the app is one screen tall and only the panes scroll. A phone scrolls the
   page itself, with the tabs, a chat's header and its message box stuck to the edges:
   Safari doesn't shrink the page for the keyboard but slides the screen over it, and a
   scrolling box inside the page then fights that slide. */
#app { max-width: 640px; height: 100dvh; margin: 0 auto; display: flex; flex-direction: column;
  padding-top: env(safe-area-inset-top, 0px); }
#view:focus { outline: none; }
#view { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; }
#view > :not(.chat) { flex: none; }
#app:not(.in-chat) #view { padding-bottom: env(safe-area-inset-bottom, 0px); }
@media (min-width: 680px) { #app { border-inline: 1px solid var(--ink); } }

.bar { flex: none; display: flex; align-items: center; gap: 10px; min-height: 56px; padding: 6px var(--gutter);
  border-bottom: 1px solid var(--ink); }
.bar h1 { flex: 1; min-width: 0; font-size: 1.25rem; line-height: 1.2; }
.bar small { display: block; font-size: .85rem; }
.manage { flex: none; padding: 8px var(--gutter); border-bottom: 1px solid var(--ink); }
.manage .actions { flex-wrap: wrap; align-items: center; margin: 8px 0 0; }
.bar .who { flex: 1; min-width: 0; }

/* The three screens, always in view. The lit one is where you are. */
.tabs { flex: none; display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; padding: 8px var(--gutter);
  border-bottom: 2px solid var(--ink); }
.tab { min-width: 0; min-height: 44px; border: 2px solid var(--ink); font-weight: 700; }
.tab[aria-current] { background: var(--ink); color: var(--paper); }
.tab.news::after { content: ""; display: inline-block; width: 8px; height: 8px; margin-left: 6px; background: currentColor; }
.in-chat #view { overflow: hidden; }

/* Spirits: each with its own build. They blink all the time (app.js), and one that is
   thinking also looks about and sways. --pace keeps two spirits out of step. */
.avatar { flex: none; display: block; width: 52px; height: 52px; overflow: visible; }
.avatar.tiny { width: 32px; height: 32px; }
.bar .avatar { width: 40px; height: 40px; }
.avatar.person { display: grid; place-items: center; border: 2px solid var(--ink); font-size: 1.4rem; font-weight: 700; }
.bar .avatar.person { font-size: 1.1rem; }
.avatar.person.tiny { font-size: 1rem; }
/* A group: its initial in a box within a box, where a person has one box. */
.avatar.person.group { border: 6px double var(--ink); }
/* A chat's way back, on a phone, where the tabs give way to it. */
.back { flex: none; display: grid; place-items: center; width: 44px; height: 44px; margin-left: -10px; }
.back:active { background: var(--ink); color: var(--paper); }
.spirit { color: inherit; font-weight: inherit; text-align: inherit; }
.spirit:active { background: var(--ink); color: var(--paper); }
.spirit:active .avatar { filter: invert(1); }
/* The spirits are white in both themes, so on a turned-over (black) row in the light they need no flip. */
:root[data-theme="light"] svg.avatar { filter: none !important; }
.eyes { transform-box: fill-box; transform-origin: center; }
.avatar.thinking { transform-origin: 50% 100%; animation: sway calc(3.5s + 1.5s * var(--pace)) ease-in-out calc(-5s * var(--pace)) infinite; }
.thinking .gaze { animation: gaze calc(7s + 3s * var(--pace)) ease-in-out calc(-10s * var(--pace)) infinite; }
@keyframes sway { 0%, 100% { transform: rotate(-3deg); } 50% { transform: rotate(3deg); } }
@keyframes gaze {
  0%, 16%, 46%, 58%, 88%, 100% { transform: translate(0, 0); }
  22%, 40% { transform: translate(-1.5px, -1px); }
  64%, 82% { transform: translate(1.5px, -.5px); }
}
.dots span { animation: dot 1.4s infinite; }
.dots span:nth-child(2) { animation-delay: .2s; }
.dots span:nth-child(3) { animation-delay: .4s; }
@keyframes dot { 0%, 100% { opacity: .15; } 40% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .avatar.thinking, .thinking .gaze, .dots span { animation: none; } }

/* Lists */
h2 { font-size: 1rem; padding: 18px var(--gutter) 6px; }
summary { display: flex; align-items: center; gap: 8px; min-height: 48px; padding-inline-end: var(--gutter); cursor: pointer; list-style: none; }
summary::-webkit-details-marker { display: none; }
summary h2 { padding: 8px 0 8px var(--gutter); }
summary::after { content: "+"; margin-left: auto; font-size: 1.4rem; font-weight: 700; line-height: 1; }
details[open] > summary::after { content: "−"; }
/* Дела, Купить, Заметки: the page's three sections, ruled off from each other. The folds
   inside a section are smaller, set in and marked by a line down their left. */
#view > details > summary { border-top: 2px solid var(--ink); }
#view > details:first-of-type > summary { border-top: 0; }
#view > details > summary h2 { font-size: 1.25rem; }
/* Выйти: apart from the settings above it. */
#view > .leave { margin-top: 24px; border-top: 2px solid var(--ink); }
h3 { margin: 0; font-size: .95rem; }
h3.lead { padding: 4px var(--gutter) 2px; font-weight: 400; font-style: italic; }
details.sub { margin: 8px 0 0 var(--gutter); border-left: 2px solid var(--ink); }
details.sub > summary { min-height: 40px; padding-inline: var(--gutter); }
details.sub > summary h3 { font-weight: 400; }
details.sub[open] > summary h3 { font-weight: 700; }
details.sub > summary::after { font-size: 1.1rem; }
.planned { border-bottom: 1px dotted var(--ink); } /* a plan's parts and its step are one line of the list */
.planned > .row { border-bottom: 0; min-height: 0; padding-block: 4px; }
.planned > .row:first-child { padding-top: 10px; }
details.part > summary { min-height: 40px; padding-inline: var(--gutter); }
details.part > summary::after { font-size: 1.1rem; }
.step { display: flex; align-items: center; gap: 12px; padding: 8px var(--gutter); }
.step small { display: block; }
.step .finished { text-decoration: line-through; }
.form-head { display: flex; align-items: center; gap: 12px; }
.row { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px; min-height: 68px; padding: 10px var(--gutter);
  border-bottom: 1px dotted var(--ink); }
.row.wide { width: 100%; flex-wrap: nowrap; text-align: left; }
.row.head { border-bottom-style: solid; }
.row.wide:active { background: var(--ink); color: var(--paper); }
.row.wide:active .avatar { filter: invert(1); }
.row.wide:active .avatar.person { filter: none; }
.grow { flex: 1 1 180px; min-width: 0; display: flex; flex-direction: column; overflow-wrap: anywhere; }
.grow small { font-size: .85rem; }
.grow .first-step { font-style: italic; }
.grow .finished { font-weight: 400; text-decoration: line-through; }
.note { white-space: pre-wrap; }
.chat-top { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.chat-top small { flex: none; }
.chat-top b { min-width: 0; }
.chat-bottom { display: flex; align-items: center; gap: 8px; min-height: 22px; }
.preview { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.unread .preview { font-weight: 700; }
.count { flex: none; min-width: 22px; padding: 0 5px; background: var(--ink); color: var(--paper); font-size: .8rem;
  font-weight: 700; line-height: 22px; text-align: center; }
.row.wide:active .count { background: var(--paper); color: var(--ink); }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.row.wide:focus-visible { outline-offset: -4px; }
.actions { flex: none; display: flex; gap: 8px; margin-left: auto; }
.pad { padding: 12px var(--gutter); }
.hint { font-size: .9rem; }

/* Buttons. Pressing inverts: there are no shades to fade through. */
.small, .big { border: 2px solid var(--ink); font-weight: 700; }
.small { min-height: 44px; padding: 0 12px; }
.big { width: 100%; min-height: 50px; }
.primary { background: var(--ink); color: var(--paper); }
.small:active, .big:active, .tab:active { background: var(--ink); color: var(--paper); }
.primary:active, .tab[aria-current]:active { background: var(--paper); color: var(--ink); }
/* Nothing to do yet: the outline goes dotted, as the send button's does. */
.big:disabled, .big:disabled:active { background: var(--paper); color: var(--ink); border-style: dotted; cursor: default; }
.link { min-height: 44px; font-weight: 700; text-decoration: underline; }
.error { border: 2px solid var(--ink); border-left-width: 8px; padding: 8px 12px; font-weight: 700; }
.error::first-letter { text-transform: uppercase; }
@media (hover: hover) {
  .small:hover, .big:hover, .tab:hover { background: var(--ink); color: var(--paper); }
  .primary:hover, .tab[aria-current]:hover { background: var(--paper); color: var(--ink); }
  .row.wide:hover b { text-decoration: underline; }
  .link:hover { text-decoration-thickness: 3px; }
  .spirit:hover { text-decoration: underline; }
  .big:disabled:hover { background: var(--paper); color: var(--ink); }
}
#view > .error { margin: 8px var(--gutter); }

/* Chat */
.chat { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 12px; padding: var(--gutter); }
.chat > .first { margin-top: auto; }
.msg { max-width: 85%; white-space: pre-wrap; overflow-wrap: anywhere; }
.msg.user { align-self: flex-end; padding: 8px 12px; background: var(--ink); color: var(--paper); }
.msg.assistant { align-self: flex-start; align-items: flex-start; max-width: 100%; display: flex; gap: 10px; }
.msg.assistant .text { min-width: 0; padding-top: 2px; }
.draft { display: grid; gap: 8px; margin-top: 8px; padding: 10px 12px; border: 2px solid var(--ink); }
.draft .head { display: flex; align-items: center; gap: 12px; }
.draft .grow { min-width: 0; }
.msg .draft b { display: block; text-decoration: none; }
.draft small { display: block; }
.draft p { margin: 0; font-size: .9rem; }
.msg a { color: inherit; }
.stamp { display: block; font-size: .82rem; }
.msg.user .stamp { text-align: right; }
.jump { flex: none; align-self: center; margin-block: 8px; }
.offline { flex: none; text-align: center; border-top: 1px dotted var(--ink); padding-block: 4px; }
[hidden] { display: none !important; }
.sender { display: block; font-size: .875rem; font-weight: 700; }
.day { align-self: center; font-size: .85rem; font-weight: 700; }
.unread-mark { align-self: stretch; text-align: center; border-top: 1px solid currentColor; padding-top: 4px; scroll-margin-top: calc(var(--tabs, 0px) + 72px); }
.waits { display: flex; flex-direction: column; gap: 12px; }
.waits:empty { display: none; }
.offers { flex: none; display: flex; gap: 8px; overflow-x: auto; padding-inline: var(--gutter); }
.offers:not(:empty) { padding-block: 8px; border-top: 1px solid var(--ink); }
.offers button { flex: none; }
.msg b { font-weight: 700; text-decoration: underline; }
.compose { flex: none; display: flex; align-items: flex-end; gap: 8px; border-top: 1px solid var(--ink);
  padding: 8px var(--gutter) calc(8px + env(safe-area-inset-bottom, 0px)); }
.compose:focus-within { padding-bottom: 8px; } /* the keyboard covers the home bar */
/* A chat sits between two bold lines: under the spirit's name, and over whatever starts the
   bottom block (offers, photos or the message box); the lines inside that block stay thin. */
.in-chat #view > .bar { border-bottom-width: 2px; }
.foot > .offers:not(:empty), .foot > .tray:not(:empty), .foot > .compose { border-top-width: 2px; }
.offers:not(:empty) ~ .tray, .offers:not(:empty) ~ .compose, .tray:not(:empty) ~ .compose { border-top-width: 1px; }
.foot { flex: none; display: flex; flex-direction: column; }
.compose textarea { flex: 1; min-width: 0; height: 46px; max-height: 140px; resize: none; overflow-y: hidden; overscroll-behavior: contain; }
.send { flex: none; display: grid; place-items: center; width: 52px; height: 46px; border: 2px solid var(--ink); }
.send:disabled { background: var(--paper); color: var(--ink); border-style: dotted; }
.attach { background: var(--paper); color: var(--ink); width: 46px; }
.tray { flex: none; display: flex; gap: 8px; overflow-x: auto; padding-inline: var(--gutter); }
.tray:not(:empty) { padding-block: 8px; border-top: 1px solid var(--ink); }
.picked { flex: none; position: relative; }
.picked img { display: block; width: 72px; height: 72px; object-fit: cover; border: 2px solid var(--ink); }
/* The ✕ is drawn small, but takes a finger's worth around it. */
.picked button { position: absolute; top: 0; right: 0; min-width: 0; min-height: 0; width: 28px; height: 28px; padding: 0; line-height: 1; }
.picked button::after { content: ""; position: absolute; inset: -8px; }
.picked .preparing { display: block; width: 72px; height: 72px; border: 2px dashed var(--ink); }
.msg.user.pending { opacity: .6; }
.msg.user.pending .stamp { font-style: italic; }
.photos { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 4px; }
.photos a { display: block; }
.photos img { display: block; max-width: min(260px, 100%); max-height: 260px; object-fit: contain; }

/* Forms */
.part { display: contents; }
input[type=text], input[type=password], input[type=email], input:not([type]) { width: 100%; background: none; border: 0;
  border-bottom: 2px solid var(--ink); border-radius: 0; padding: 8px 0; }
input:not([type=checkbox], [type=file]):focus-visible { outline: none; border-bottom-width: 3px; }
select, textarea { width: 100%; background: var(--paper); border: 2px solid var(--ink); border-radius: 0; padding: 8px; }
textarea { resize: vertical; }
select:focus-visible, textarea:focus-visible { outline: none; border-width: 3px; padding: 7px; }
label { display: grid; gap: 4px; font-weight: 700; }
.form { display: grid; gap: 16px; padding: var(--gutter); }
fieldset { border: 2px solid var(--ink); margin: 0; padding: 4px 12px 8px; display: grid; }
legend { font-weight: 700; padding: 0 4px; }
/* Your language and the household's, one above the other. */
.languages { display: grid; gap: 16px; }
.languages .hint { margin: 4px 0 0; font-weight: 400; }
/* Your name: the field, a line on it, and Save under them at the side. */
.form.name > button { justify-self: start; padding-inline: 20px; }
.form.name .hint { margin: -8px 0 0; }
.daily > .row { padding-inline: 0; min-height: 52px; }
.daily > .row:nth-last-child(2) { border-bottom: 0; }
/* A spirit's memory and notebook: folded lists inside the fieldset, a page read in place. */
.kept { gap: 4px; }
.kept details.part > summary { padding-inline: 0; }
.kept details > .row { padding-inline: 0; align-items: start; }
.kept details > .row:last-child { border-bottom: 0; }
.kept .grow { display: grid; gap: 2px; min-width: 0; overflow-wrap: anywhere; }
.kept .actions { display: flex; gap: 6px; flex: none; }
.page-text { margin-top: 6px; font-weight: 400; }
.check { display: flex; align-items: center; gap: 10px; min-height: 44px; font-weight: 400; }
.check input { appearance: none; flex: none; width: 22px; height: 22px; margin: 0; border: 2px solid var(--ink); }
.check input:checked { background: var(--ink); box-shadow: inset 0 0 0 3px var(--paper); }
.check input:disabled { border-style: dotted; }
.check input[type=radio] { border-radius: 50%; }
input[type=file] { width: 100%; }
::file-selector-button { min-height: 44px; margin-right: 12px; padding: 0 12px; background: var(--paper); color: var(--ink);
  border: 2px solid var(--ink); font: inherit; font-weight: 700; }
.meter { height: 12px; margin-top: 6px; border: 2px solid var(--ink); }
.meter span { display: block; height: 100%; background: var(--ink); }
.spend .grow { display: grid; gap: 4px; }
.row.wide:active .meter, .cell:hover .meter, .cell[aria-pressed="true"] .meter { border-color: var(--paper); }
.row.wide:active .meter span, .cell:hover .meter span, .cell[aria-pressed="true"] .meter span { background: var(--paper); }
.usage { padding-inline: 0; gap: 0; }
.usage > p { padding: 0 var(--gutter); }
.usage .grow { display: grid; gap: 2px; min-width: 0; }

/* Login */
.login { max-width: 380px; margin: 0 auto; padding: 14vh var(--gutter) 24px; display: grid; gap: 20px; }
.login img { display: block; width: 112px; height: 112px; }
.login h1 { font-size: 2rem; line-height: 1.1; }
.login form { display: grid; gap: 18px; }
.login button { min-height: 50px; font-weight: 700; }
/* the border matches the fill at rest, so it only shows once hover/press flips the button to paper */
.login button.primary { border: 3px solid var(--ink); }
/* Next comes first, so Enter goes forward, and it's drawn first too, so the order the keyboard
   takes is the order on screen. */
.login .steps { display: flex; gap: 12px; }
/* The welcome's buttons stay on screen however long the step: a list to choose from
   scrolls under them. */
.welcome .steps { position: sticky; bottom: 0; z-index: 1; margin-inline: -4px; padding: 12px 4px max(12px, env(safe-area-inset-bottom, 0px));
  background: var(--paper); border-top: 1px dotted var(--ink); }
.login .steps .primary { flex: 1; }
.login .back-step { padding: 0 20px; border: 3px solid var(--ink); }
.login .back-step:active { background: var(--ink); color: var(--paper); }
@media (hover: hover) { .login .back-step:hover { background: var(--ink); color: var(--paper); } }
/* The language list at the top of a page before the app, each language in itself: small,
   at the side, out of the way of the form, and first to be found. */
.login .langpick { display: flex; gap: 8px; justify-self: end; align-items: center; margin-top: -10vh; }
.langpick label { display: flex; gap: 8px; align-items: center; font-size: .9rem; }
.langpick select { width: auto; min-height: 40px; padding: 4px 8px; }
.langpick select:focus-visible { padding: 3px 7px; }
.langpick button { min-height: 40px; padding: 0 12px; }

/* A phone's task: Готово beside the text, where the thumb is, and Обсудить, which is
   asked for less, as a link under it. Two lines instead of three. */
@media (max-width: 1099px) {
  .row.task { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; column-gap: 12px; row-gap: 0; }
  .row.task > .actions { display: contents; }
  .row.task > .actions > :first-child { grid-column: 3; grid-row: 1; }
  .row.task .discuss { grid-column: 2; grid-row: 2; justify-self: start; min-height: 36px; padding: 0; border: 0; font-size: .9rem;
    background: none; color: var(--ink); text-decoration: underline; }
  .row.task .discuss:active { background: var(--ink); color: var(--paper); }
}

/* Desktop: the phone's one column becomes a room. The chat list and the day stay in view,
   and everything gets denser, because a mouse needs less than a thumb. */
#rail, #side, #side-toggle { display: none; }
@media (max-width: 1099px) {
  #app { height: auto; min-height: 100dvh; padding-top: 0; }
  #view, .in-chat #view { overflow: visible; }
  .tabs { position: sticky; top: 0; z-index: 2; background: var(--paper);
    padding-top: calc(8px + env(safe-area-inset-top, 0px)); }
  /* A chat has the whole screen: its header, with the way back, is where the tabs were. */
  .in-chat .tabs { display: none; }
  .in-chat #view > .bar { position: sticky; top: 0; z-index: 1; background: var(--paper);
    padding-top: calc(6px + env(safe-area-inset-top, 0px)); }
  .chat { flex: 1 0 auto; overflow: visible; }
  .foot { position: sticky; bottom: 0; z-index: 1; background: var(--paper); }
}
@media (min-width: 1100px) {
  html { scrollbar-color: var(--ink) var(--paper); }
  body { font-size: 16px; }
  #app { max-width: none; border: 0; display: grid; grid-template-rows: auto minmax(0, 1fr);
    grid-template-columns: 320px minmax(0, 1fr); }
  .tabs { grid-area: 1 / 1; gap: 6px; padding: 8px 12px; border-right: 1px solid var(--ink); }
  .tab { min-height: 34px; font-size: .9rem; }
  #rail { display: block; grid-area: 2 / 1; overflow-y: auto; scrollbar-width: thin; border-right: 1px solid var(--ink); }
  #view { grid-area: 1 / 2 / 3 / 3; scrollbar-width: thin; }

  /* The open chat is lit, as the tab of the screen you're on is. */
  #rail .row { min-height: 60px; padding: 8px 12px; gap: 10px; }
  #rail .avatar { width: 40px; height: 40px; }
  #rail .avatar.person { font-size: 1.1rem; }
  #rail b { font-weight: 400; }
  #rail .unread b { font-weight: 700; }
  #rail .preview { font-weight: 400; }
  .row.current { background: var(--ink); color: var(--paper); }
  .row.current .avatar { filter: invert(1); }
  .row.current .avatar.person { filter: none; border-color: var(--paper); }
  .row.current .count { background: var(--paper); color: var(--ink); }

  /* A line of about 70 characters, however wide the screen. */
  .chat { --room: max(24px, calc((100% - 760px) / 2)); padding-inline: var(--room); gap: 10px; }
  .compose { --room: max(24px, calc((100% - 760px) / 2)); padding-inline: var(--room); }
  .offers { padding-inline: max(24px, calc((100% - 760px) / 2)); }
  .bar { padding-inline: 24px; }
  .back { display: none; } /* the list is beside the chat */
  .manage { padding-inline: 24px; }
  .msg.assistant .avatar.tiny { width: 40px; height: 40px; }
  .msg.assistant { gap: 12px; }

  .small { min-height: 34px; padding: 0 10px; font-size: .9rem; }
  .big { min-height: 42px; }
  .row { min-height: 56px; padding-block: 8px; }
  .row .avatar { width: 40px; height: 40px; }
  .row .avatar.tiny { width: 32px; height: 32px; }
  summary { min-height: 40px; }
  h2 { padding-top: 14px; }

  #view > :is(.form, .form-head) { width: 100%; max-width: 808px; margin-inline: auto; padding-inline: 24px; }
  #view > .form-head { padding-top: 20px; font-size: 1.6rem; }
  #view:has(.form.two) > :is(.form, .form-head) { max-width: 1048px; }
  .form.two { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: 16px 32px; align-items: start; }
  .form.two > .big { grid-column: 1 / -1; }
  .part { display: grid; gap: 16px; }
  .form.two textarea { min-height: 280px; }
}
@media (min-width: 1200px) {
  #app { grid-template-columns: 320px minmax(0, 1fr) 340px; }
  #app.plain { grid-template-columns: 320px minmax(0, 1fr); }
  /* One corner, whichever pane is under it. */
  .in-chat #side-toggle { display: block; position: fixed; top: 11px; right: 16px; z-index: 1; width: 132px; padding-inline: 0; }
  .in-chat #view .bar { padding-right: 164px; }
  .in-chat:not(.plain) #view .bar { padding-right: 24px; }
  #side .bar { padding-right: 164px; }
  #side { display: block; grid-area: 1 / 3 / 3 / 4; overflow-y: auto; scrollbar-width: thin; border-left: 1px solid var(--ink); }
  .plain #side { display: none; }
  #side .bar { position: sticky; top: 0; z-index: 1; padding-inline: 16px; background: var(--paper); }
  #side .bar h1 { font-size: 1.1rem; }
  #side .grow > b { font-weight: 400; }
  #side .row { padding: 8px 16px; gap: 6px 10px; }
  #side .small { min-height: 30px; padding: 0 8px; font-size: .85rem; }
}
@media (min-width: 1100px) and (hover: hover) {
  #rail .row.wide:not(.current):hover { background: var(--ink); color: var(--paper); }
  #rail .row.wide:not(.current):hover .avatar { filter: invert(1); }
  #rail .row.wide:not(.current):hover .avatar.person { filter: none; border-color: var(--paper); }
  #rail .row.wide:hover b { text-decoration: none; }
}
/* Дела: a week across, one list below. The lit day is the one you're reading. */
@media (min-width: 1100px) {
  .strip { flex: none; display: grid; grid-template-columns: 1.5fr repeat(6, 1fr) 1fr; border-bottom: 1px solid var(--ink); }
  .cell { display: flex; flex-direction: column; gap: 2px; min-width: 0; min-height: 104px; padding: 10px 12px; text-align: left;
    border-right: 1px dotted var(--ink); }
  .cell:last-child { border-right: 0; border-left: 1px solid var(--ink); }
  .cell:first-child { border-right: 1px solid var(--ink); }
  .cell small { font-size: .875rem; }
  .cell b { font-size: 1.5rem; line-height: 1.15; min-height: 1.15em; }
  .cell:disabled { cursor: default; }
  .cell:disabled b { font-weight: 400; }
  .cell[aria-pressed="true"] { background: var(--ink); color: var(--paper); }
  .cell[aria-pressed="true"] .avatar { filter: invert(1); }
  .cell:focus-visible { outline-offset: -4px; }
  .faces { display: flex; align-items: center; flex-wrap: wrap; gap: 1px; margin-top: auto; min-height: 24px; }
  .row .faces .avatar, .faces .avatar.tiny { width: 24px; height: 24px; }
  .faces small { margin-left: 2px; font-size: .8rem; }
  /* Only the list scrolls: the strip and the list's title stay where they are. The room
     is padding, so the scrollbar is at the pane's edge rather than beside the text. */
  #view:has(> .plan-list) { overflow: hidden; }
  #view > .plan-list { flex: 1; min-height: 0; overflow-y: auto; scrollbar-width: thin;
    padding: 0 max(24px, calc((100% - 760px) / 2)) 32px; }
  .plan-list:focus { outline: none; }
  .plan-head { position: sticky; top: 0; z-index: 1; display: flex; align-items: baseline; gap: 12px; padding: 20px 0 12px;
    background: var(--paper); border-bottom: 1px solid var(--ink); }
  .plan-head h1 { font-size: 1.6rem; line-height: 1.2; }
  .plan-head .actions { align-self: center; }
  .plan-list .row { padding-inline: 0; }
  .plan-list h2 { padding-inline: 0; }
  .plan-list > .hint { padding-top: 16px; }
  .plan-list .row .grow > b { font-weight: 400; }
}
@media (min-width: 1100px) and (hover: hover) {
  .cell:not(:disabled, .out, [aria-pressed="true"]):hover { background: var(--ink); color: var(--paper); }
  .cell:not(:disabled, .out, [aria-pressed="true"]):hover .avatar { filter: invert(1); }
}
/* Lines run straight across the panes, top and bottom, and a chat rests on its message box. */
@media (min-width: 1100px) {
  .tabs { min-height: 56px; align-content: center; grid-template-columns: 1fr 1fr 1.35fr; }
  .bar { height: 56px; min-height: 0; padding-block: 0; }
  #rail { display: flex; flex-direction: column; }
  #rail > .row { flex: none; }
  #rail > .pad { position: sticky; bottom: 0; margin-top: auto; padding: 8px 12px; background: var(--paper); border-top: 1px solid var(--ink); }
  #rail > .pad .big { min-height: 46px; }
  .chat::before { content: ""; margin-top: auto; }

  /* Forms: the one thing to press is the size of a button, not of the page. */
  #view > .form > .big.primary { justify-self: start; width: auto; padding-inline: 32px; }
  .form.two > .big:first-child { grid-column: 2; justify-self: end; width: auto; min-height: 34px; margin-top: -60px; padding-inline: 12px; font-size: .9rem; }
}
/* Настройки: the same strip, and spirits as a gallery of faces. */
@media (min-width: 1100px) {
  .strip.even { display: flex; }
  .strip.even .cell { flex: 1 1 0; }
  .strip.even .cell { border-right: 1px solid var(--ink); border-left: 0; }
  /* Theme, language and leaving: settings rather than things to look at, so a quiet column of links at the end. */
  .strip.even .cell.out { flex: none; width: auto; min-width: 200px; align-items: flex-start; justify-content: center; gap: 0; border-right: 0; }
  .prefs .link { min-height: 30px; font-size: .9rem; font-weight: 400; text-align: left; }
  .prefs .link[aria-pressed="true"] { font-weight: 700; }
  .prefs form .link { font-weight: 700; }
  .strip.even .meter { margin-top: auto; height: 8px; }
  .waits-mark { margin-top: auto; font-weight: 700; }
  .tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); padding-top: 8px; }
  .tile { display: flex; flex-direction: column; align-items: center; gap: 6px; min-height: 148px; padding: 16px 8px; text-align: center; }
  .tile .avatar, .tile .plus { width: 72px; height: 72px; }
  .tile .plus { display: grid; place-items: center; font-size: 2.6rem; line-height: 1; font-weight: 700; }
  .tile small { font-size: .875rem; }
}
@media (min-width: 1100px) and (hover: hover) {
  .tile:hover { background: var(--ink); color: var(--paper); }
  .tile:hover .avatar { filter: invert(1); }
}
/* With a mouse, a row's buttons wait under the pointer, so a list reads as a list. */
@media (min-width: 1100px) and (hover: hover) {
  :is(.plan-list, #side) .row:not(.ask) { position: relative; flex-wrap: nowrap; }
  :is(.plan-list, #side) .row:not(.ask) > :is(.actions, .small) {
    position: absolute; right: 0; top: 50%; translate: 0 -50%; margin: 0; padding-left: 12px;
    background: var(--paper); box-shadow: 0 0 0 6px var(--paper); opacity: 0; }
  #side .row > :is(.actions, .small) { right: 12px; }
  :is(.plan-list, #side) .row:not(.ask) > .small { padding-left: 10px; }
  :is(.plan-list, #side) .row:not(.ask):is(:hover, :focus-within) > :is(.actions, .small) { opacity: 1; }
}
.login ul.spirits { margin: 0; padding-left: 1.2em; display: grid; gap: 6px; }
.login fieldset.folks { border: 0; margin: 0; padding: 0; display: grid; gap: 4px; }
.login fieldset.folks .check { padding: 2px 0; }
.login h2 { font-size: 1.2rem; padding: 0; }
.login fieldset.group { border: 0; margin: 0; padding: 0; display: grid; gap: 4px; }
.login fieldset.group legend { padding: 0 0 4px; font-weight: 700; }
.login fieldset.group .check { align-items: flex-start; padding: 6px 0; }
.login fieldset.group .check input { margin-top: 2px; }
.admin { max-width: 1100px; margin: 0 auto; padding: 24px var(--gutter); display: grid; gap: 16px; }
.admin .scroll { overflow-x: auto; }
.admin table { border-collapse: collapse; width: 100%; font-variant-numeric: tabular-nums; }
.admin th, .admin td { text-align: left; vertical-align: top; padding: 6px 10px 6px 0; border-bottom: 1px solid var(--ink); }
.admin tr.here td:first-child { border-left: 4px solid var(--ink); padding-left: 6px; }
.admin .feedback { border-left: 4px solid var(--ink); padding-left: 12px; white-space: pre-wrap; }
.legal { max-width: 720px; margin: 0 auto; padding: 32px var(--gutter) 48px; display: grid; gap: 14px; line-height: 1.5; }
.legal h1 { font-size: 2rem; line-height: 1.1; }
.legal h2 { font-size: 1.2rem; margin-top: 10px; }
.legal ul, .legal ol { padding-left: 1.3em; display: grid; gap: 8px; }


/* Before the app: what's new to the signup, the welcome and the page waiting for an address. */
.langpick .globe { flex: none; fill: none; stroke: var(--ink); stroke-width: 1.6; }
.login .notice { border: 2px solid var(--ink); padding: 8px 12px; }
.login a.button { display: grid; place-items: center; min-height: 50px; padding: 0 16px; font-weight: 700; text-decoration: none; text-align: center; }
.login a.button.primary { border: 3px solid var(--ink); }
@media (hover: hover) { .login a.button.primary:hover { background: var(--paper); color: var(--ink); } }
/* Second buttons on these pages are outlined, so they read as buttons beside the main one. */
.login form > button:not(.primary, .link), .login .share-buttons button:not(.primary) { border: 3px solid var(--ink); padding: 0 16px; }
@media (hover: hover) { .login form > button:not(.primary, .link):hover, .login .share-buttons button:not(.primary):hover { background: var(--ink); color: var(--paper); } }
.login [aria-invalid="true"] { outline: 3px solid var(--ink); outline-offset: 2px; }
.login .error a { margin-left: 4px; }
.login div.consent { display: grid; gap: 6px; }
.login .consent .check, .login label.check.consent { align-items: flex-start; }
.login .consent .check input, .login label.check.consent input { margin-top: 2px; }
.login div.consent .hint { margin: 0 0 0 32px; }
.login .progress { margin: -8px 0 -12px; font-size: .9rem; font-weight: 700; letter-spacing: .02em; }
.login details.change > summary, .login details.more > summary { min-height: 44px; padding: 0; font-weight: 700; }
.login details.change form { padding-top: 8px; }
.login .homes { display: grid; gap: 10px; }
.sharelink { display: grid; gap: 10px; }
.share-buttons { display: flex; gap: 12px; }
.share-buttons button { flex: 1; }
.share-buttons button[hidden] { display: none; }
.sharelink .hint:empty { display: none; }

/* Spirits drawn by the server (drawingSVG): the same colours app.js gives them. */
svg.avatar .fi { fill: var(--spirit-body); }
svg.avatar .fp { fill: var(--spirit-mark); }
svg.avatar .fn { fill: none; }
svg.avatar .fe { fill: var(--spirit-edge); }
svg.avatar .si { stroke: var(--spirit-body); }
svg.avatar .sp { stroke: var(--spirit-mark); }
svg.avatar .sn { stroke: none; }
svg.avatar .se { stroke: var(--spirit-edge); }
.login ul.spirits.faces { list-style: none; padding: 0; gap: 10px; }
.login ul.spirits.faces li { display: flex; align-items: center; gap: 12px; }
.login .check svg.avatar { width: 40px; height: 40px; }
.login .folk-chosen { border: 2px solid var(--ink); padding: 14px 12px; gap: 12px; }
.login .folk-chosen svg.avatar { width: 52px; height: 52px; margin-bottom: 6px; }
.login .folk-chosen small { display: block; font-size: .9rem; }
.login details.more { display: grid; gap: 4px; }
.login details.more[open] { padding-bottom: 4px; }
.login .folk-face svg.avatar { width: 72px; height: 72px; }
/* In the welcome the step's own button is the main one: sharing is outlined beside it. */
.welcome .share-buttons button.primary { background: var(--paper); color: var(--ink); }
@media (hover: hover) { .welcome .share-buttons button.primary:hover { background: var(--ink); color: var(--paper); } }

/* A form on its way, sent once (once.js). */
button[aria-busy="true"] { opacity: 0.6; cursor: progress; }

/* A message held at the bottom of the screen: a word that something's saved, or an error,
   which stays until it's closed. It keeps clear of a phone's home bar and the compose row. */
.toast-box { position: fixed; left: 0; right: 0; bottom: calc(var(--toast-lift, 0px) + max(12px, env(safe-area-inset-bottom, 0px)));
  display: grid; justify-items: center; padding-inline: 16px; pointer-events: none; z-index: 20; }
.toast { pointer-events: auto; max-width: 640px; width: fit-content; margin: 0; padding: 10px 14px; background: var(--ink); color: var(--paper);
  font-weight: 700; border: 2px solid var(--ink); }
.toast.error { display: flex; align-items: center; gap: 12px; background: var(--paper); color: var(--ink); }
.toast[hidden] { display: none; }
#app.in-chat ~ .toast-box, body:has(#app.in-chat) .toast-box { --toast-lift: 72px; }
a.button { display: grid; place-items: center; min-height: 50px; padding: 0 16px; font-weight: 700; text-decoration: none; text-align: center;
  background: var(--ink); color: var(--paper); border: 3px solid var(--ink); }
@media (hover: hover) { a.button:hover { background: var(--paper); color: var(--ink); } }
