/* ---------------------------------------------------------------------------
   Oeee Cafe's design system

   One file of tokens and components for every page, the painter pages
   included. The site's pages load it through base.jinja, before style.css;
   the painter and tegaki pages load it after their own sheet.

   Three rules keep it safe to load anywhere:

   - Components are classes (`.ds-button`, `.ds-select`). Nothing here styles
     a bare element, except inside `.ds-page` -- the body class only
     base.jinja sets -- where controls with no class of their own take the
     system's look by default. The painter's controls all have classes, and
     its pages are not `.ds-page`, so none of this reaches NEO's chrome.
   - Nothing here reads the site's --main-* variables; the painter redefines
     those as NEO's.
   - Firefox 56 reads it unbuilt: no flex `gap`, no :is() or :where(),
     prefixed `appearance` and `user-select`. What that engine cannot do
     (accent-color, for one) is an enhancement, never the only styling.

   Light and dark follow the site's one rule: the system decides unless the
   painter's switch has chosen, in which case `data-theme` on the root says.
   --------------------------------------------------------------------------- */
:root {
  /* Type: the system's own faces, with its Korean and Japanese ones named,
     so a title in either sits in the same family as the chrome. */
  --ds-font: -apple-system, BlinkMacSystemFont, "Segoe UI Variable Text", "Segoe UI",
    "Apple SD Gothic Neo", "Malgun Gothic", "Hiragino Sans", "Yu Gothic UI", system-ui,
    Arial, sans-serif;
  --ds-text-xs: 11px;
  --ds-text-s: 12px;
  --ds-text-m: 13px;
  --ds-text-base: 14px;
  --ds-text-l: 16px;
  --ds-text-xl: 20px;
  --ds-text-2xl: 26px;
  /* Space: a 4px scale. */
  --ds-space-1: 4px;
  --ds-space-2: 8px;
  --ds-space-3: 12px;
  --ds-space-4: 16px;
  --ds-space-5: 24px;
  --ds-space-6: 32px;
  /* Corners: small for controls, medium for what floats. Drawings have
     none -- they are framed the way the painter frames its canvas. */
  --ds-radius-s: 6px;
  --ds-radius-m: 10px;
  --ds-control-height: 30px;
  /* Ground: NEO's own -- the lavender the painter has always stood on, and
     its 14px grid -- so the site and the painter are one surface. Dark is
     NEO's night blue. */
  --ds-ground: #ccccff;
  --ds-grid: #bbbbff;
  /* The grid line as a solid colour, for grounds drawn by the painter. */
  --ds-grid-solid: #bbbbff;
  /* Surfaces: what sits on the ground -- fields, menus, cards. */
  --ds-surface: #f2f2ff;
  --ds-field: #ffffff;
  /* Ink, in three strengths. Muted is 5.4:1 on the ground; faint is for
     placeholders and disabled text only. */
  --ds-ink: #22223a;
  --ds-muted: #4a4a78;
  --ds-faint: #7777a3;
  /* Lines. */
  --ds-line: rgba(60, 60, 130, 0.18);
  --ds-line-strong: rgba(60, 60, 130, 0.35);
  --ds-frame: #666699;
  /* States, laid over whatever is beneath. */
  --ds-hover: rgba(60, 60, 150, 0.08);
  --ds-selected: rgba(60, 60, 150, 0.15);
  --ds-focus: #4f8a10;
  /* The cucumber: the one colour that means "do this". Dark ink on it in
     both themes -- white on lime is under 2:1. */
  --ds-accent: #c4ee62;
  --ds-accent-hover: #b5e24c;
  --ds-accent-ink: #1c2811;
  --ds-accent-line: rgba(60, 103, 18, 0.35);
  /* Signals. */
  --ds-badge: #ef842d;
  --ds-danger: #dc2626;
  --ds-danger-hover: #b91c1c;
  --ds-danger-ink: #ffffff;
  /* Depth. */
  --ds-shadow-raise: 0 1px 2px rgba(40, 40, 90, 0.12);
  --ds-shadow-menu: 0 8px 24px rgba(40, 40, 90, 0.22);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ds-ground: #17172b;
    --ds-grid: #22223f;
    --ds-grid-solid: #22223f;
    --ds-surface: #23233c;
    --ds-field: #1d1d33;
    --ds-ink: #dcdcea;
    --ds-muted: #a3a3bd;
    --ds-faint: #77779a;
    --ds-line: rgba(200, 200, 255, 0.14);
    --ds-line-strong: rgba(200, 200, 255, 0.28);
    --ds-frame: #9595a7;
    --ds-hover: rgba(200, 200, 255, 0.08);
    --ds-selected: rgba(200, 200, 255, 0.15);
    --ds-focus: #c4ee62;
    --ds-badge: #ff8c00;
    --ds-danger: #ef4444;
    --ds-danger-hover: #dc2626;
    --ds-shadow-raise: 0 1px 2px rgba(0, 0, 0, 0.4);
    --ds-shadow-menu: 0 8px 24px rgba(0, 0, 0, 0.5);
  }
}

:root[data-theme="dark"] {
  --ds-ground: #17172b;
  --ds-grid: #22223f;
  --ds-grid-solid: #22223f;
  --ds-surface: #23233c;
  --ds-field: #1d1d33;
  --ds-ink: #dcdcea;
  --ds-muted: #a3a3bd;
  --ds-faint: #77779a;
  --ds-line: rgba(200, 200, 255, 0.14);
  --ds-line-strong: rgba(200, 200, 255, 0.28);
  --ds-frame: #9595a7;
  --ds-hover: rgba(200, 200, 255, 0.08);
  --ds-selected: rgba(200, 200, 255, 0.15);
  --ds-focus: #c4ee62;
  --ds-badge: #ff8c00;
  --ds-danger: #ef4444;
  --ds-danger-hover: #dc2626;
  --ds-shadow-raise: 0 1px 2px rgba(0, 0, 0, 0.4);
  --ds-shadow-menu: 0 8px 24px rgba(0, 0, 0, 0.5);
}

/* ---------------------------------------------------------------------------
   Behaving like an application

   What gave the site away as a web page was less its colours than its
   manners: every word selectable, a hand over every control, drawings that
   come loose when dragged, a page that bounces past its ends, and a window
   that goes blank between pages. On `.ds-page` pages:

   - Nothing is selectable but what is worth copying -- what people wrote,
     and every field. Content opts in with `.ds-selectable`, or by being one
     of the containers named below.
   - The cursor is the arrow. A hyperlink keeps its hand; controls do not.
   - Links are never underlined; in what people wrote, where a link is text
     among text, the accent's green tells it apart.
   - Images and links do not drag out of the window.
   - The page does not rubber-band, and the document's own ground is the
     window's, so nothing white shows at its edges or between pages.
   --------------------------------------------------------------------------- */
:root {
  --ds-link: #2f5410;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ds-link: #b5e24c;
  }
}

:root[data-theme="dark"] {
  --ds-link: #b5e24c;
}

html {
  background-color: var(--ds-ground);
  overscroll-behavior: none;
}

.ds-page {
  overscroll-behavior: none;
  cursor: default;
  -moz-user-select: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

.ds-page input,
.ds-page textarea,
.ds-page select,
.ds-page [contenteditable],
.ds-selectable,
.ds-page .post-title,
.ds-page .post-content,
.ds-page .comment-content,
.ds-page .guestbook-entry pre,
.ds-page .guestbook-reply pre,
.ds-page .community-description,
.ds-page .draft-description {
  -moz-user-select: text;
  -webkit-user-select: text;
  user-select: text;
  -webkit-touch-callout: default;
}

.ds-page input,
.ds-page textarea,
.ds-page [contenteditable] {
  cursor: text;
}

.ds-page a,
.ds-page a:hover {
  text-decoration: none;
  cursor: pointer;
}

/* In what people wrote, a link is told apart from the text around it by
   colour alone. */
.ds-selectable a,
.ds-page .post-content a,
.ds-page .comment-content a,
.ds-page .community-description a {
  color: var(--ds-link);
}

.ds-page img,
.ds-page a {
  -webkit-user-drag: none;
}

/* Controls answer to the arrow, as a window's controls do. */
.ds-button,
.ds-select,
.ds-page button,
.ds-page select,
.ds-page summary,
.ds-page label,
.ds-page input[type="submit"],
.ds-page input[type="button"],
.ds-page input[type="checkbox"],
.ds-page input[type="radio"],
.ds-page input[type="range"],
.ds-segmented > *,
.toolbar-links a,
.toolbar-end a,
.toolbar-menu summary,
.toolbar-draw {
  cursor: default;
}

/* A drawing in a grid is a thing you open, like an icon, not a link you
   follow. */
.ds-page .posts-grid a,
.ds-page .posts-grid img {
  cursor: default;
}

/* ---------------------------------------------------------------------------
   The content area

   A window scrolls its content, not itself: the toolbar stays put and the
   scrollbar runs from under it to the bottom, as in any application. So on
   `.ds-page` the body is a column that exactly fills the window -- the
   header (the toolbar, then any messages) and below it `main.ds-content`,
   which is the only thing that scrolls. The grid is drawn on the content
   area and scrolls with it.

   Phones keep the page scrolling: a scrolling area inside the page stops a
   phone browser from tucking its address bar away, which costs more screen
   than the toolbar staying put would save.

   What depended on the window scrolling: htmx's `revealed` is an
   IntersectionObserver against the viewport, which sees inside a scrolling
   area, so infinite scroll is unchanged; where you were on a page is kept by
   toolbar.jinja, since browsers only restore the window's own scroll.
   --------------------------------------------------------------------------- */
@media (min-width: 601px) {
  html {
    height: 100%;
  }

  .ds-page {
    display: -webkit-box;
    display: flex;
    -webkit-box-orient: vertical;
    flex-direction: column;
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
  }

  .ds-page > header {
    flex: 0 0 auto;
  }

  .ds-page > main.ds-content {
    flex: 1 1 auto;
    min-height: 0;
    overflow-x: hidden;
    overflow-y: auto;
    overscroll-behavior: contain;
    /* Its own ground under its own grid, covering the body's, so the two
       never show out of step. */
    background-color: var(--ds-ground);
    background-image: linear-gradient(var(--ds-grid) 1px, transparent 1px),
      linear-gradient(90deg, var(--ds-grid) 1px, transparent 1px);
    background-size: 14px 14px;
    background-attachment: local;
  }
}

.ds-content:focus {
  outline: none;
}

/* ---------------------------------------------------------------------------
   The toolbar

   The window's title bar: the site's name, the sections as tabs, and at the
   end the notifications bell, Draw and the account. In the desktop app the
   window's own controls sit over its left end.
   --------------------------------------------------------------------------- */
.nav-bar {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  z-index: 50;
  background-color: var(--ds-ground);
  border-bottom: 1px solid var(--ds-line);
  color: var(--ds-ink);
  font-family: var(--ds-font);
  font-size: 13px;
  line-height: 1.5;
  view-transition-name: toolbar;
  -moz-user-select: none;
  -webkit-user-select: none;
  user-select: none;
}

#menubar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  min-height: 52px;
}

.nav-bar #menubar {
  padding: 0 12px;
}

.toolbar-name,
.toolbar-name:visited {
  margin-right: var(--ds-space-3);
  padding: 4px 6px;
  color: var(--ds-ink);
  font-size: var(--ds-text-l);
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 20px;
  text-decoration: none;
  white-space: nowrap;
}

.toolbar-links,
.toolbar-end {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}

/* The sections read as one control at rest, not only under the pointer: a
   segmented group, the current one raised out of it. */
.toolbar-links {
  padding: 2px;
  border-radius: 8px;
  background-color: var(--ds-hover);
}

.toolbar-links > * + * {
  margin-left: 2px;
}

.toolbar-end {
  margin-left: auto;
}

.toolbar-end > * + * {
  margin-left: 6px;
}

.toolbar-links a,
.toolbar-end > a,
.toolbar-end .toolbar-icon,
.toolbar-menu summary,
.toolbar-draw {
  display: inline-block;
  margin-top: 0;
  margin-bottom: 0;
  padding: 4px 11px;
  border: 0;
  border-radius: 6px;
  background: none;
  color: var(--ds-ink);
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  line-height: 20px;
  text-decoration: none;
  white-space: nowrap;
}

.toolbar-links a:visited,
.toolbar-end a:visited {
  color: var(--ds-ink);
}

.toolbar-links a:hover,
.toolbar-end > a:hover,
.toolbar-end .toolbar-icon:hover,
.toolbar-menu summary:hover,
.toolbar-menu[open] summary {
  background-color: var(--ds-hover);
}

.nav-bar .toolbar-links a[aria-current="page"],
.nav-bar .toolbar-links a[aria-current="page"]:hover {
  background-color: var(--ds-surface);
  box-shadow: 0 0 0 0.5px var(--ds-line), var(--ds-shadow-raise);
  font-weight: 600;
}

/* A plain link at the toolbar's end -- signing in, the site's about page --
   is drawn as a button, since that is what it is there. */
.toolbar-end > a:not(.toolbar-draw):not(.toolbar-icon) {
  border: 1px solid var(--ds-line-strong);
  background-color: var(--ds-surface);
  box-shadow: var(--ds-shadow-raise);
}

.toolbar-end > a:not(.toolbar-draw):not(.toolbar-icon):hover {
  background-color: var(--ds-ground);
}

.toolbar-end .toolbar-icon {
  position: relative;
  padding: 5px 8px 3px;
}

/* Tailwind's reset, on the painter pages, makes every svg and img a block;
   the toolbar's icons sit in a line of text. */
.nav-bar svg {
  display: inline-block;
}

.toolbar-icon svg {
  vertical-align: top;
}

.toolbar-end .toolbar-icon .toolbar-badge {
  position: absolute;
  top: -2px;
  right: -4px;
  margin-left: 0;
}

/* Drawing is what the site is for, so it is the one filled control: the
   cucumber's lime, with dark ink in both themes. */
.toolbar-end .toolbar-draw,
.toolbar-end a.toolbar-draw:visited {
  background-color: var(--ds-accent);
  color: var(--ds-accent-ink);
  box-shadow: inset 0 0 0 1px rgba(60, 103, 18, 0.35);
  font-weight: 600;
}

.toolbar-end .toolbar-draw:hover {
  background-color: var(--ds-accent-hover);
}

.toolbar-draw svg {
  margin-right: 6px;
  vertical-align: -2px;
}

.toolbar-end form {
  margin: 0;
}

.toolbar-badge {
  display: inline-block;
  min-width: 16px;
  margin-left: 4px;
  padding: 0 4px;
  border-radius: 8px;
  background-color: var(--ds-badge);
  color: #000;
  font-size: 10px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

.toolbar-avatar {
  display: inline-block;
  width: 28px;
  height: 28px;
  border-radius: 14px;
  background-color: var(--ds-accent);
  color: var(--ds-accent-ink);
  font-size: 13px;
  font-weight: 700;
  line-height: 28px;
  text-align: center;
}

.toolbar-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-left: -8px;
  border-radius: 4px;
  background-color: var(--ds-danger);
  vertical-align: top;
}

.toolbar-menu {
  position: relative;
}

.toolbar-menu summary {
  display: block;
  padding: 4px;
  list-style: none;
}

.toolbar-menu summary::-webkit-details-marker {
  display: none;
}

.toolbar-menu-items {
  position: absolute;
  top: 100%;
  right: 0;
  z-index: 60;
  min-width: 200px;
  margin-top: 6px;
  padding: 4px;
  border: 1px solid var(--ds-line);
  border-radius: 10px;
  background-color: var(--ds-surface);
  box-shadow: var(--ds-shadow-menu);
}

.toolbar-menu-who {
  padding: 8px 10px;
  border-bottom: 1px solid var(--ds-line);
  margin-bottom: 4px;
  font-size: 13px;
  line-height: 18px;
}

.toolbar-menu-who span {
  display: block;
  color: var(--ds-muted);
}

.toolbar-menu-items a {
  display: block;
  padding: 6px 10px;
  border-radius: 6px;
  color: var(--ds-ink);
  font-size: 13px;
  text-decoration: none;
}

.toolbar-menu-items a:visited {
  color: var(--ds-ink);
}

.toolbar-menu-items a:hover {
  background-color: var(--ds-hover);
}

/* The theme choice, at the foot of a toolbar menu. */
.toolbar-theme {
  margin-top: 4px;
  padding: 8px 10px 6px;
  border-top: 1px solid var(--ds-line);
}

.toolbar-menu-items .toolbar-theme:first-child {
  margin-top: 0;
  border-top: 0;
}

.toolbar-theme-label {
  display: block;
  margin-bottom: 6px;
  color: var(--ds-muted);
  font-size: var(--ds-text-s);
}

.toolbar-theme .ds-segmented {
  display: block;
  text-align: center;
}

.toolbar-menu summary svg {
  vertical-align: middle;
}

/* A phone keeps the account on the first line and gives the sections a line
   of their own, scrolled sideways rather than wrapped. */
@media (max-width: 600px) {
  .toolbar-links {
    order: 3;
    width: 100%;
    flex-wrap: nowrap;
    overflow-x: auto;
    padding-bottom: 6px;
    scrollbar-width: none;
  }

  .toolbar-links::-webkit-scrollbar {
    display: none;
  }
}

.post-image {
  max-width: 100%;
  display: flex;
  object-fit: contain;
}

.post-image-full {
  width: 100%;
  height: auto;
  display: flex;
  object-fit: contain;
}


/* ---------------------------------------------------------------------------
   Controls

   Each component is a class, and inside `.ds-page` the same look is the
   default for a control that has no class of its own -- so a form written
   plainly comes out right, and a control that already carries a component
   of its own is left alone until it is converted. The defaults sit before
   style.css in the cascade, so a page's own contextual rule still wins a tie.
   --------------------------------------------------------------------------- */

/* The drop-down arrow, drawn in each theme's muted ink. A custom property can
   carry a url(), which is how one rule gets two colours of arrow. */
:root {
  --ds-select-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%234a4a78' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ds-select-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%23a3a3bd' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  }
}

:root[data-theme="dark"] {
  --ds-select-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%23a3a3bd' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

/* Buttons. Secondary is the default; primary is the one thing a view asks you
   to do, and there should be one of it.

   No component here sets a margin. The defaults for unclassed controls are
   more specific than a page's own spacing rules (`.actions > * { ... }`),
   so a margin set here would quietly undo the page's layout. */
.ds-button,
.ds-page button:not([class]),
.ds-page input[type="submit"]:not([class]),
.ds-page input[type="button"]:not([class]),
.ds-page input[type="reset"]:not([class]) {
  display: inline-block;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  min-height: var(--ds-control-height);
  padding: 5px 14px;
  border: 1px solid var(--ds-line-strong);
  border-radius: var(--ds-radius-s);
  background-color: var(--ds-surface);
  box-shadow: var(--ds-shadow-raise);
  color: var(--ds-ink);
  font-family: var(--ds-font);
  font-size: var(--ds-text-m);
  font-weight: 500;
  line-height: 18px;
  text-align: center;
  text-decoration: none;
  vertical-align: middle;
  white-space: nowrap;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
}

.ds-button:hover,
.ds-page button:not([class]):hover,
.ds-page input[type="submit"]:not([class]):hover,
.ds-page input[type="button"]:not([class]):hover,
.ds-page input[type="reset"]:not([class]):hover {
  background-color: var(--ds-ground);
}

.ds-button-primary,
.ds-button-primary:visited {
  border-color: var(--ds-accent-line);
  background-color: var(--ds-accent);
  color: var(--ds-accent-ink);
  font-weight: 600;
}

.ds-button-primary:hover {
  background-color: var(--ds-accent-hover);
}

.ds-button-quiet,
.ds-button-quiet:visited {
  border-color: transparent;
  background-color: transparent;
  box-shadow: none;
}

.ds-button-quiet:hover {
  background-color: var(--ds-hover);
}

.ds-button-danger,
.ds-button-danger:visited {
  border-color: transparent;
  background-color: var(--ds-danger);
  color: var(--ds-danger-ink);
  font-weight: 600;
}

.ds-button-danger:hover {
  background-color: var(--ds-danger-hover);
}

/* For a row of actions inside a list -- a comment's, a notification's --
   where a full-size button would outweigh what it acts on. */
.ds-button-small,
.ds-page .ds-button-small {
  min-height: 24px;
  padding: 2px 9px;
  font-size: var(--ds-text-s);
  line-height: 18px;
}

.ds-button[disabled],
.ds-page button:not([class])[disabled],
.ds-page input[type="submit"]:not([class])[disabled] {
  opacity: 0.45;
  cursor: default;
  pointer-events: none;
}

/* Text fields and text areas. */
.ds-input,
.ds-textarea,
.ds-page input[type="text"]:not([class]),
.ds-page input[type="email"]:not([class]),
.ds-page input[type="password"]:not([class]),
.ds-page input[type="url"]:not([class]),
.ds-page input[type="search"]:not([class]),
.ds-page input[type="number"]:not([class]),
.ds-page input:not([type]):not([class]),
.ds-page textarea:not([class]) {
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  min-height: var(--ds-control-height);
  max-width: 100%;
  padding: 5px 10px;
  border: 1px solid var(--ds-line-strong);
  border-radius: var(--ds-radius-s);
  background-color: var(--ds-field);
  color: var(--ds-ink);
  font-family: var(--ds-font);
  font-size: var(--ds-text-base);
  line-height: 18px;
}

.ds-textarea,
.ds-page textarea:not([class]) {
  padding: 8px 10px;
  line-height: 20px;
}

/* Native drop-downs, drawn to match: the closed control is ours, the open
   list is the system's own -- which is what a window's list should be, and
   is keyboard- and screen-reader-complete without a line of script. */
.ds-select,
.ds-page select:not([class]) {
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  min-height: var(--ds-control-height);
  max-width: 100%;
  padding: 5px 32px 5px 10px;
  border: 1px solid var(--ds-line-strong);
  border-radius: var(--ds-radius-s);
  background-color: var(--ds-surface);
  background-image: var(--ds-select-arrow);
  background-position: right 10px center;
  background-repeat: no-repeat;
  box-shadow: var(--ds-shadow-raise);
  color: var(--ds-ink);
  font-family: var(--ds-font);
  font-size: var(--ds-text-m);
  line-height: 18px;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
}

/* Firefox before 64 draws its own arrow through `appearance: none` unless
   the text is indented out from under it. */
.ds-select,
.ds-page select:not([class]) {
  text-indent: 0.01px;
  text-overflow: "";
}

.ds-select::-ms-expand,
.ds-page select:not([class])::-ms-expand {
  display: none;
}

.ds-select:hover,
.ds-page select:not([class]):hover {
  background-color: var(--ds-ground);
}

.ds-select option,
.ds-page select:not([class]) option {
  background-color: var(--ds-surface);
  color: var(--ds-ink);
}

/* Checkboxes, radios and sliders stay the system's own, tinted with the
   cucumber where the engine can. */
.ds-page input[type="checkbox"],
.ds-page input[type="radio"],
.ds-page input[type="range"],
.ds-check {
  accent-color: #6fa22b;
}

/* One focus ring for everything you can type into or press. */
.ds-button:focus,
.ds-input:focus,
.ds-textarea:focus,
.ds-select:focus,
.ds-page button:not([class]):focus,
.ds-page input:not([class]):focus,
.ds-page textarea:not([class]):focus,
.ds-page select:not([class]):focus {
  outline: 2px solid var(--ds-focus);
  outline-offset: 1px;
}

.ds-input::-webkit-input-placeholder,
.ds-page input:not([class])::-webkit-input-placeholder,
.ds-page textarea:not([class])::-webkit-input-placeholder {
  color: var(--ds-faint);
}

.ds-input::-moz-placeholder,
.ds-page input:not([class])::-moz-placeholder,
.ds-page textarea:not([class])::-moz-placeholder {
  color: var(--ds-faint);
  opacity: 1;
}

.ds-input::placeholder,
.ds-page input:not([class])::placeholder,
.ds-page textarea:not([class])::placeholder {
  color: var(--ds-faint);
}

.ds-label {
  display: block;
  margin-bottom: var(--ds-space-1);
  color: var(--ds-ink);
  font-size: var(--ds-text-m);
  font-weight: 600;
}

.ds-help {
  display: block;
  margin-top: var(--ds-space-1);
  color: var(--ds-muted);
  font-size: var(--ds-text-s);
}

/* ---------------------------------------------------------------------------
   Forms

   The site's forms already share a small vocabulary, and the system draws
   it rather than asking every form to be rewritten:

   - a `fieldset` is a card, and its `legend` the card's title;
   - a field is a label above its control -- a `<p>` in a fieldset, or a
     `.form-group` or `.form-field` -- with optional `.ds-help` below;
   - a checkbox or radio sits beside its label instead (`.form-group-checkbox`,
     or a label that follows the box);
   - `.form-actions` is the row of buttons at the end;
   - a form's submit button is its primary action, so it is the lime one.
     A destructive submit says so with `.ds-button-danger`.

   The legend floats because a legend otherwise sits on its fieldset's
   border; floated, it is the first line inside the card.
   --------------------------------------------------------------------------- */
.ds-fieldset,
.ds-page fieldset:not([class]) {
  min-width: 0;
  margin: 0 0 var(--ds-space-4);
  padding: 20px;
  border: 1px solid var(--ds-line);
  border-radius: var(--ds-radius-m);
  background-color: var(--ds-surface);
  box-shadow: var(--ds-shadow-raise);
}

.ds-fieldset > legend,
.ds-page fieldset:not([class]) > legend {
  float: left;
  width: 100%;
  margin: 0 0 var(--ds-space-4);
  padding: 0;
  border: 0;
  background: none;
  color: var(--ds-ink);
  font-size: var(--ds-text-l);
  font-weight: 700;
  line-height: 22px;
}

.ds-fieldset > legend + *,
.ds-page fieldset:not([class]) > legend + * {
  clear: both;
}

.ds-page fieldset:not([class]) > p {
  margin: 0 0 var(--ds-space-4);
}

.ds-page fieldset:not([class]) > p:last-child {
  margin-bottom: 0;
}

/* A field's label, above its control. */
.ds-page fieldset label[for]:not([class]),
.form-group > label,
.form-field > label {
  display: block;
  margin-bottom: var(--ds-space-1);
  color: var(--ds-ink);
  font-size: var(--ds-text-m);
  font-weight: 600;
}

/* A checkbox's or radio's label, beside it. */
.ds-page fieldset input[type="checkbox"] + label[for],
.ds-page fieldset input[type="radio"] + label[for] {
  display: inline;
  margin: 0 0 0 var(--ds-space-2);
  font-weight: 400;
}

/* Controls in a field run the width of the card; a one-line field stops
   where a line of text would. */
.ds-page fieldset input:not([type]):not([class]),
.ds-page fieldset input[type="text"]:not([class]),
.ds-page fieldset input[type="email"]:not([class]),
.ds-page fieldset input[type="password"]:not([class]),
.ds-page fieldset input[type="url"]:not([class]),
.ds-page fieldset input[type="search"]:not([class]),
.ds-page fieldset select:not([class]),
.form-group input[type="text"],
.form-group select,
.form-field input[type="text"],
.form-field select {
  width: 100%;
  max-width: 420px;
}

.ds-page fieldset textarea:not([class]),
.form-group textarea,
.form-field textarea {
  width: 100%;
  min-height: 100px;
  resize: vertical;
}

/* `.form-field` is the same thing under the name the community forms use. */
.form-group,
.form-field {
  margin-bottom: var(--ds-space-4);
}

.form-group-checkbox {
  display: flex;
  align-items: center;
}

.form-group-checkbox > label {
  display: inline;
  margin: 0 0 0 var(--ds-space-2);
  font-weight: 400;
}

.form-actions,
.ds-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  margin-top: var(--ds-space-5);
}

.form-actions > * + *,
.ds-actions > * + * {
  margin-left: var(--ds-space-2);
}

/* The submit is the form's primary action. More specific than an unclassed
   button's default, so it wins; a page's own contextual rule for its
   submit, where one survives, still outranks both. */
.ds-page form input[type="submit"]:not([class]),
.ds-page form button[type="submit"]:not([class]),
.ds-page form button:not([type]):not([class]) {
  border-color: var(--ds-accent-line);
  background-color: var(--ds-accent);
  color: var(--ds-accent-ink);
  font-weight: 600;
}

.ds-page form input[type="submit"]:not([class]):hover,
.ds-page form button[type="submit"]:not([class]):hover,
.ds-page form button:not([type]):not([class]):hover {
  background-color: var(--ds-accent-hover);
}

/* ---------------------------------------------------------------------------
   Grouping
   --------------------------------------------------------------------------- */

/* A segmented control: two to five choices of one thing. The chosen one is
   marked by aria-pressed, aria-current or `.is-selected`. */
.ds-segmented {
  display: inline-block;
  padding: 2px;
  border-radius: 7px;
  background-color: var(--ds-hover);
  white-space: nowrap;
}

/* Written against `.ds-page .ds-segmented > button` as well, because an
   unclassed button's default is exactly that specific and comes earlier. */
.ds-segmented > *,
.ds-page .ds-segmented > button {
  display: inline-block;
  margin: 0;
  padding: 3px 12px;
  border: 0;
  border-radius: 5px;
  background: none;
  color: var(--ds-ink);
  font-family: var(--ds-font);
  font-size: var(--ds-text-m);
  font-weight: 500;
  line-height: 20px;
  min-height: 0;
  box-shadow: none;
  text-decoration: none;
}

.ds-page .ds-segmented > button:hover,
.ds-segmented > *:hover {
  background-color: var(--ds-hover);
}

.ds-segmented > * + *,
.ds-page .ds-segmented > button + button {
  margin-left: 2px;
}

.ds-segmented > [aria-pressed="true"],
.ds-segmented > [aria-current="page"],
.ds-segmented > .is-selected,
.ds-page .ds-segmented > button[aria-pressed="true"],
.ds-page .ds-segmented > button[aria-pressed="true"]:hover {
  background-color: var(--ds-surface);
  box-shadow: 0 0 0 0.5px var(--ds-line), var(--ds-shadow-raise);
  font-weight: 600;
}

.ds-badge {
  display: inline-block;
  min-width: 16px;
  padding: 0 5px;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  border-radius: 8px;
  background-color: var(--ds-badge);
  color: #000;
  font-size: 10px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
}

/* A surface on the ground: settings groups, forms, anything that is a box. */
.ds-card {
  padding: var(--ds-space-4);
  border: 1px solid var(--ds-line);
  border-radius: var(--ds-radius-m);
  background-color: var(--ds-surface);
  box-shadow: var(--ds-shadow-raise);
}

/* ---------------------------------------------------------------------------
   The painter's window

   What belongs to drawing -- a replay, a drawing's details, its comments --
   sits in NEO's chrome: its lavender panel, its bevel, its title bar with
   the three grab dots. Written out here rather than borrowed from the
   painter's sheet, which these pages do not load.
   --------------------------------------------------------------------------- */
:root {
  --ds-neo-panel: #ccccff;
  --ds-neo-ink: #2a2a44;
  --ds-neo-text: #4a4a78;
  --ds-neo-light: #ffffff;
  --ds-neo-shadow: #8f8fb3;
  --ds-neo-title-from: #9397b2;
  --ds-neo-title-to: #b1d6fd;
  --ds-neo-title-ink: #ffffff;
  --ds-neo-well: #e9e9ff;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ds-neo-panel: #30304b;
    --ds-neo-ink: #dcdcea;
    --ds-neo-text: #c1c1cd;
    --ds-neo-light: #63637e;
    --ds-neo-shadow: #1c1c21;
    --ds-neo-title-from: #24243a;
    --ds-neo-title-to: #3d4f70;
    --ds-neo-title-ink: #d7d7e4;
    --ds-neo-well: #20203a;
  }
}

:root[data-theme="dark"] {
  --ds-neo-panel: #30304b;
  --ds-neo-ink: #dcdcea;
  --ds-neo-text: #c1c1cd;
  --ds-neo-light: #63637e;
  --ds-neo-shadow: #1c1c21;
  --ds-neo-title-from: #24243a;
  --ds-neo-title-to: #3d4f70;
  --ds-neo-title-ink: #d7d7e4;
  --ds-neo-well: #20203a;
}

.ds-window {
  border-style: solid;
  border-width: 1px;
  border-color: var(--ds-neo-light) var(--ds-neo-shadow) var(--ds-neo-shadow) var(--ds-neo-light);
  background-color: var(--ds-neo-panel);
  box-shadow: 0 0 0 1px #000000;
  color: var(--ds-neo-ink);
}

.ds-window-title {
  height: 18px;
  padding: 0 4px;
  background: -webkit-linear-gradient(left, var(--ds-neo-title-from), var(--ds-neo-title-to));
  background: linear-gradient(to right, var(--ds-neo-title-from), var(--ds-neo-title-to));
  color: var(--ds-neo-title-ink);
  font-family: Arial, Helvetica, sans-serif;
  font-size: 12px;
  line-height: 18px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The three grab dots, drawn by the title bar itself so markup stays one
   element. */
.ds-window-title::before {
  content: "";
  display: inline-block;
  width: 3px;
  height: 3px;
  margin: 0 12px 0 1px;
  border-radius: 2px;
  background-color: rgba(255, 255, 255, 0.7);
  box-shadow: 5px 0 0 rgba(255, 255, 255, 0.7), 10px 0 0 rgba(255, 255, 255, 0.7);
  vertical-align: middle;
}

.ds-window-body {
  padding: var(--ds-space-3);
}

/* ---------------------------------------------------------------------------
   The keyboard shortcuts list

   A panel over the page, opened by `?` or the desktop app's Help menu. The
   keys are drawn as keys.
   --------------------------------------------------------------------------- */
.ds-shortcuts {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 200;
  display: -webkit-box;
  display: flex;
  -webkit-box-align: center;
  align-items: center;
  -webkit-box-pack: center;
  justify-content: center;
  background-color: rgba(20, 20, 50, 0.35);
}

.ds-shortcuts[hidden] {
  display: none;
}

.ds-shortcuts-panel {
  width: 360px;
  max-width: calc(100% - 32px);
  padding: 16px 20px 20px;
  border: 1px solid var(--ds-line);
  border-radius: var(--ds-radius-m);
  background-color: var(--ds-surface);
  box-shadow: var(--ds-shadow-menu);
  color: var(--ds-ink);
  font-size: var(--ds-text-m);
}

.ds-shortcuts-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}

.ds-shortcuts-head h2 {
  margin: 0;
  font-size: var(--ds-text-l);
}

.ds-shortcuts dl {
  display: grid;
  grid-template-columns: max-content 1fr;
  grid-gap: 8px 16px;
  gap: 8px 16px;
  align-items: center;
  margin: 0;
}

.ds-shortcuts dt {
  color: var(--ds-muted);
  white-space: nowrap;
}

.ds-shortcuts dd {
  margin: 0;
}

.ds-shortcuts kbd {
  display: inline-block;
  min-width: 20px;
  padding: 1px 6px;
  border: 1px solid var(--ds-line-strong);
  border-bottom-width: 2px;
  border-radius: 5px;
  background-color: var(--ds-field);
  color: var(--ds-ink);
  font-family: var(--ds-font);
  font-size: var(--ds-text-s);
  font-weight: 600;
  line-height: 18px;
  text-align: center;
}

/* ---------------------------------------------------------------------------
   Skeletons

   What the content area shows the moment a page is asked for, drawn by
   toolbar.jinja in the shape of the page to come: a feed's grid of squares
   at the reader's own count a row, or a title and lines. It breathes rather
   than spins, and holds still for reduced motion.
   --------------------------------------------------------------------------- */
.ds-skeleton {
  padding-top: 2px;
}

.ds-skeleton-bar,
.ds-skeleton-square {
  border-radius: 4px;
  background-color: var(--ds-hover);
  -webkit-animation: ds-breathe 1.4s ease-in-out infinite;
  animation: ds-breathe 1.4s ease-in-out infinite;
}

.ds-skeleton-heading {
  width: 180px;
  height: 22px;
  margin-bottom: var(--ds-space-4);
}

.ds-skeleton-square {
  border-radius: 0;
  padding-top: 100%;
}

.ds-skeleton-caption {
  height: 12px;
  margin-top: 10px;
  width: 70%;
}

.ds-skeleton-caption.short {
  width: 40%;
  margin-top: 6px;
}

.ds-skeleton-line {
  height: 14px;
  margin-bottom: 14px;
}

.ds-skeleton-line.short {
  width: 60%;
}

@-webkit-keyframes ds-breathe {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}

@keyframes ds-breathe {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}

@media (prefers-reduced-motion: reduce) {
  .ds-skeleton-bar,
  .ds-skeleton-square {
    -webkit-animation: none;
    animation: none;
  }
}

/* ---------------------------------------------------------------------------
   Modal dialogs

   A panel over a dimmed page -- a report, a confirmation. The page shows and
   hides it by its `display`, so this only lays it out.
   --------------------------------------------------------------------------- */
.ds-modal {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 200;
  -webkit-box-align: center;
  align-items: center;
  -webkit-box-pack: center;
  justify-content: center;
  background-color: rgba(20, 20, 50, 0.35);
}

.ds-modal-panel {
  width: 480px;
  max-width: calc(100% - 32px);
  padding: 16px 20px 20px;
  border: 1px solid var(--ds-line);
  border-radius: var(--ds-radius-m);
  background-color: var(--ds-surface);
  box-shadow: var(--ds-shadow-menu);
  color: var(--ds-ink);
}

.ds-modal-panel h2 {
  margin: 0 0 var(--ds-space-3);
  font-size: var(--ds-text-l);
}
