/*
 * The look of the help desk, after the mockup that the owner accepted: the bar with the app chips, the count tiles,
 * the tabs, the rows of conversations and of reported problems, the status pills, the "Why Claude needs you" box, the
 * mail cards, the two action boxes and the buttons; and, in the same style, the settings. The help desk serves every
 * app, so it has a calm neutral palette of its own, not an app's.
 *
 * Every colour is a custom property below, defined for light and redefined for dark: a colour written anywhere else
 * would not change with the theme. Text has a contrast of at least 4.5:1 with what it stands on, and the edge of a
 * form control and the focus ring at least 3:1, in both themes.
 *
 * The pages have no inline style and no script, which the Content-Security-Policy blocks: the look is all here.
 * Narrower than 640 px, a row, the action boxes and an app's configuration take one column each.
 */

:root {
  color-scheme: light dark;
  --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;

  --page: #ffffff;               /* the page, the chips, the form controls */
  --inset: #f4f5f7;              /* a step off the page: tiles, the why box, the details, a row under the pointer */
  --sunk: #e6e8ec;               /* plain buttons, count and held pills */
  --sunk-hover: #d9dce2;
  --border: #d9dce1;             /* lines between parts */
  --field-border: #868c96;       /* the edge of a form control */
  --text: #1b1d21;
  --text-muted: #545a65;         /* learner lines, notes, times, labels */
  --text-faint: #676d78;         /* placeholders */
  --accent: #1f5fbf;             /* the chosen chip, buttons, the active tab's line, "Claude is answering" */
  --accent-hover: #184f9f;
  --on-accent: #ffffff;
  --accent-ink: #1d5bb8;         /* text in the accent: links, "Waiting for learner" */
  --accent-tint: #eaf1fb;        /* Claude's mails, "Waiting for learner" */
  --accent-tint-border: #b3cbed;
  --alert: #c0362c;              /* "Needs you", the edge of the why box, deleting */
  --alert-hover: #a32d24;
  --on-alert: #ffffff;
  --alert-ink: #b3322a;          /* the Needs you count, error messages */
  --ok-tint: #e5f3e9;            /* solved */
  --ok-ink: #1c6534;
  --warn-tint: #fcf2d6;          /* banners */
  --warn-border: #e5c979;
  --warn-ink: #5f4500;
  --focus: #1f5fbf;
  --selection: #cfe0f7;
}

@media (prefers-color-scheme: dark) {
  :root {
    --page: #25262a;
    --inset: #1b1c1f;
    --sunk: #35373c;
    --sunk-hover: #41444a;
    --border: #3d4046;
    --field-border: #7d838d;
    --text: #eceef2;
    --text-muted: #adb3bd;
    --text-faint: #9aa0aa;
    --accent: #2f6fd0;
    --accent-hover: #2860b8;
    --on-accent: #ffffff;
    --accent-ink: #8db9f6;
    --accent-tint: #1f2d42;
    --accent-tint-border: #3a5680;
    --alert: #c43d33;
    --alert-hover: #a9342b;
    --on-alert: #ffffff;
    --alert-ink: #ff8f84;
    --ok-tint: #1d3526;
    --ok-ink: #90d4a4;
    --warn-tint: #383019;
    --warn-border: #6a5a2c;
    --warn-ink: #f0d58c;
    --focus: #8db9f6;
    --selection: #2c4a75;
  }
}

/* ---- the page */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--page);
  color: var(--text);
  font: 1rem/1.5 var(--font);
  accent-color: var(--accent);
  caret-color: var(--accent);
  /* A long address or link in a mail breaks rather than widening the page past a phone's screen. */
  overflow-wrap: anywhere;
}

h1,
h2,
h3,
p {
  margin: 0;
}

h1,
h2,
h3 {
  font-weight: 600;
  line-height: 1.3;
  text-wrap: balance;
}

h1 {
  font-size: 1.25rem;
}

h2 {
  font-size: 1.1rem;
}

h3 {
  font-size: 1rem;
}

a {
  color: var(--accent-ink);
  text-underline-offset: 0.15em;
}

a:hover {
  text-decoration-thickness: 2px;
}

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

::selection {
  background: var(--selection);
  color: var(--text);
}

img {
  max-width: 100%;
  height: auto;
}

main {
  max-width: 72rem;
  margin: 0 auto;
}

/* A page of its own, such as a conversation: its parts one under the other. */
.page {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 1rem 1rem 2rem;
}

.stack {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

/* Text for a screen reader alone, such as the heading of the list, which the mockup does not show. It is not
   display: none or visibility: hidden, which would hide it from a screen reader too. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---- the bar: the help desk's name, the app chips, the logout */

.bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  /* The bar spans the window; its content lines up with the page's. */
  padding: 0.75rem max(1rem, (100% - 72rem) / 2 + 1rem);
  border-bottom: 1px solid var(--border);
}

.bar-title {
  margin-right: 1rem;
  color: var(--text);
  font-weight: 600;
  text-decoration: none;
}

.bar-title:hover {
  text-decoration: underline;
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.chip {
  display: inline-flex;
  align-items: center;
  padding: 0.25rem 0.65rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--page);
  color: var(--text-muted);
  font-size: 0.8rem;
  text-decoration: none;
}

a.chip:not(.on):hover {
  border-color: var(--field-border);
  color: var(--text);
}

.chip.on {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--on-accent);
}

/* The link to the settings and the logout stand at the end of the bar. */
.bar-link {
  margin-left: auto;
  color: var(--text-muted);
  font-size: 0.85rem;
  text-decoration: none;
}

.bar-link:hover {
  color: var(--text);
  text-decoration: underline;
}

.bar-link[aria-current="page"] {
  color: var(--text);
  font-weight: 600;
}

.logout {
  margin: 0;
}

.banner {
  padding: 0.6rem max(1rem, (100% - 72rem) / 2 + 1rem);
  border-bottom: 1px solid var(--warn-border);
  background: var(--warn-tint);
  color: var(--warn-ink);
  font-size: 0.85rem;
}

/* ---- the count tiles */

/* A list: each tile holds its number and its label, which a screen reader reads together. */
.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 0.75rem;
  margin: 0;
  padding: 1rem;
  list-style: none;
}

.tile {
  padding: 0.75rem;
  border-radius: 8px;
  background: var(--inset);
}

.tile .n {
  font-size: 1.4rem;
  font-weight: 600;
  line-height: 1.3;
  font-variant-numeric: tabular-nums;
}

.tile .t {
  color: var(--text-muted);
  font-size: 0.75rem;
}

.tile.alert .n {
  color: var(--alert-ink);
}

/* ---- the tabs: the active one is underlined in the accent */

.tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0 1.25rem;
  padding: 0 1rem;
  border-bottom: 1px solid var(--border);
  font-size: 0.85rem;
}

.tab {
  margin-bottom: -1px;
  padding: 0.5rem 0;
  border-bottom: 2px solid transparent;
  color: var(--text-muted);
  text-decoration: none;
}

.tab:hover {
  color: var(--text);
}

.tab.on,
.tab[aria-current="page"] {
  border-bottom-color: var(--accent);
  color: var(--text);
  font-weight: 600;
}

/* A line about the tab under the tabs, such as the automatic mail that Held or junk does not list. */
.tab-note {
  padding: 0.75rem 1rem 0;
  color: var(--text-muted);
  font-size: 0.8rem;
}

/* ---- the rows: status pill, title with the learner and the note for the owner, time */

.rows {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  list-style: none;
}

.row {
  position: relative;
  display: grid;
  grid-template-columns: 9.5rem minmax(0, 1fr) auto;
  gap: 0.75rem;
  align-items: start;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border);
  font-size: 0.85rem;
}

.row:last-child {
  border-bottom: none;
}

/* The status of a row, and beside it the mark of an email that was not delivered. */
.tags {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 0.3rem;
}

/* The title of a conversation is its link, whose name is the title; the link covers the whole row, so that the row
   opens the conversation, and the rest of the row is text beside it. The focus ring goes round the row. */
.row-link {
  color: var(--text);
  font-weight: 600;
  text-decoration: none;
}

.row-link::after {
  content: "";
  position: absolute;
  inset: 0;
}

.row:has(.row-link):hover {
  background: var(--inset);
}

.row:has(.row-link):hover .row-link {
  text-decoration: underline;
}

.row-link:focus-visible {
  outline: none;
}

.row-link:focus-visible::after {
  outline: 2px solid var(--focus);
  outline-offset: -2px;
}

.who {
  color: var(--text-muted);
  font-size: 0.78rem;
}

.note {
  margin-top: 0.2rem;
  color: var(--text-muted);
  font-size: 0.8rem;
}

.when {
  color: var(--text-muted);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ---- the reported problems: rows of the list, with the learners and the kind of a problem beside its title, the
   phones, systems, dates and conversations of its reports under it, and Mark fixed or Mark done */

/* The open problems and the finished ones, under the tabs. */
.views {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.25rem;
  padding: 0.75rem 1rem 0;
  font-size: 0.8rem;
}

.view.on {
  color: var(--text);
  font-weight: 600;
  text-decoration: none;
}

.problem-title {
  font-size: 1em;
}

.facts {
  margin-top: 0.2rem;
  color: var(--text-muted);
  font-size: 0.78rem;
}

/* The state of a finished problem, in the place of its button: a pill, also where the row has one column, which
   would stretch it across the row. */
.row > .st {
  justify-self: start;
}

/* The pages of a long tab, under its rows. */
.pages {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1.25rem;
  padding: 0.75rem 1rem;
  border-top: 1px solid var(--border);
  font-size: 0.85rem;
}

.pages span {
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

/* ---- the status pills: need (Needs you), busy (Claude is answering), wait (Waiting for learner, Waiting), done
   (Solved, Solved, no reply, and a reported problem that is fixed or done), off (Held, Junk), count (the learners of a
   reported problem), kind (bug or wish, beside it), and warn (Not delivered, beside the status of a conversation that
   holds an email SES refused for good, in the colours of the banners) */

.st {
  display: inline-block;
  padding: 0.15rem 0.5rem;
  border-radius: 4px;
  background: var(--sunk);
  color: var(--text);
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1.5;
  white-space: nowrap;
}

.st.need {
  background: var(--alert);
  color: var(--on-alert);
}

.st.busy {
  background: var(--accent);
  color: var(--on-accent);
}

.st.wait {
  background: var(--accent-tint);
  color: var(--accent-ink);
}

.st.done {
  background: var(--ok-tint);
  color: var(--ok-ink);
}

.st.off {
  color: var(--text-muted);
}

.st.warn {
  background: var(--warn-tint);
  color: var(--warn-ink);
}

/* The kind of a reported problem, bug or wish, as a label beside its count: outlined, and as tall as the pill beside
   it, whose padding takes the edge. */
.st.kind {
  padding: calc(0.15rem - 1px) calc(0.5rem - 1px);
  border: 1px solid var(--field-border);
  background: transparent;
  color: var(--text-muted);
  font-weight: 400;
}

/* ---- a conversation: its line of facts, why Claude needs the owner, the mails */

/* The title of a conversation and its line of facts. */
.head {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

/* The parts after the thread, the learner's other conversations and the owner's move, stand further apart from what
   is above them than their own parts do. */
.conversation .others,
.conversation .actions {
  margin-top: 1rem;
}

.kv {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  color: var(--text-muted);
  font-size: 0.8rem;
}

.why {
  padding: 0.75rem 1rem;
  border-left: 4px solid var(--alert);
  border-radius: 4px;
  background: var(--inset);
  font-size: 0.85rem;
}

.mail {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 0.75rem 1rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 0.85rem;
}

/* The thread: the mails of a conversation, oldest first. */
.thread {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.mail.claude {
  border-color: var(--accent-tint-border);
  background: var(--accent-tint);
}

/* The owner's own replies, apart from Claude's. */
.mail.owner {
  background: var(--inset);
}

.meta {
  color: var(--text-muted);
  font-size: 0.75rem;
}

/* A mail's text keeps its lines. */
.text {
  white-space: pre-wrap;
}

/* The English text of a mail in another language, under a dashed line. */
.tr {
  padding-top: 0.4rem;
  border-top: 1px dashed var(--border);
  color: var(--text-muted);
  font-size: 0.8rem;
  white-space: pre-wrap;
}

.mail.claude .tr {
  border-top-color: var(--accent-tint-border);
}

/* The app's details of a mail: version, system, phone. */
.details {
  padding: 0.4rem 0.6rem;
  border-radius: 4px;
  background: var(--inset);
  color: var(--text-muted);
  font-family: var(--mono);
  font-size: 0.72rem;
}

.mail img {
  border: 1px solid var(--border);
  border-radius: 4px;
}

/* The pictures of a mail, each a link to the whole picture; a tall screenshot is shown smaller. */
.images {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.images img {
  display: block;
  width: auto;
  max-height: 20rem;
}

/* What the help desk says of a mail: that it joined the conversation, that it was cut or has no text, the attachments
   that were not read, and how far its mail has got: sending, tried again (warn), or not delivered (alert). */
.joined,
.cut,
.no-text,
.attachments,
.delivery {
  color: var(--text-muted);
  font-size: 0.8rem;
}

.delivery.warn {
  color: var(--warn-ink);
}

.delivery.alert {
  color: var(--alert-ink);
  font-weight: 600;
}

/* The learner's other conversations: rows of the list, in a frame of their own. */
.others {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.others h2 {
  font-size: 0.95rem;
}

.others .rows {
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 8px;
}

.label {
  color: var(--text-muted);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

/* ---- the two action boxes, side by side */

.act {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
}

.box {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.75rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 0.85rem;
}

/* The owner's move: the boxes, Mark solved, and the boxes of releasing and deleting. */
.actions {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

/* The name of a box's action, which labels its text box, as the mockup sets it. */
.box-title {
  font-size: 0.85rem;
  font-weight: 600;
}

/* Two boxes side by side are as tall as each other, and their text boxes take what their help leaves, so that their
   buttons line up. */
.act .box textarea {
  flex: 1;
}

/* A button and, beside it, what the owner should know of it, such as that it can take a minute: the note takes the
   room beside the button, and goes under it only where that room is too narrow to read. */
.submit {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
}

.submit .hint {
  flex: 1 1 14rem;
}

/* ---- forms */

.field {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

label {
  font-size: 0.8rem;
  font-weight: 600;
}

input[type="text"],
input[type="password"],
input[type="email"],
input[type="number"],
input[type="search"],
select,
textarea {
  width: 100%;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--field-border);
  border-radius: 6px;
  background: var(--page);
  color: var(--text);
  font: inherit;
  font-size: 0.9rem;
}

/* A phone zooms into a control whose text is smaller than 1rem as soon as it is touched. */
@media (pointer: coarse) {
  input[type="text"],
  input[type="password"],
  input[type="email"],
  input[type="number"],
  input[type="search"],
  select,
  textarea {
    font-size: 1rem;
  }
}

input:hover,
select:hover,
textarea:hover {
  border-color: var(--text-muted);
}

input:disabled,
select:disabled,
textarea:disabled {
  cursor: not-allowed;
  opacity: 0.6;
}

input[aria-invalid="true"],
select[aria-invalid="true"],
textarea[aria-invalid="true"] {
  border-color: var(--alert);
}

textarea {
  min-height: 4.5rem;
  line-height: 1.45;
  resize: vertical;
}

::placeholder {
  color: var(--text-faint);
  opacity: 1;
}

/* A refusal: at the top of a page, and beside the field that it is about. */
.error,
.field-error {
  color: var(--alert-ink);
  font-size: 0.85rem;
  font-weight: 600;
}

/* The refusal at the top of a page leads to the field that it is about. */
.error a {
  color: inherit;
}

/* A field that a link leads to shows with its label and its help above it. */
.box textarea,
.box input,
.field input {
  scroll-margin-top: 8rem;
}

.hint {
  color: var(--text-muted);
  font-size: 0.75rem;
}

.notice {
  padding: 0.6rem 0.75rem;
  border-radius: 6px;
  background: var(--ok-tint);
  color: var(--ok-ink);
  font-size: 0.85rem;
}

.empty {
  padding: 2rem 1rem;
  color: var(--text-muted);
  font-size: 0.9rem;
  text-align: center;
}

/* ---- buttons: accent for the action of a box, plain for the others, danger for deleting */

.btn {
  display: inline-block;
  align-self: flex-start;
  padding: 0.35rem 0.8rem;
  border: 1px solid transparent;
  border-radius: 6px;
  background: var(--accent);
  color: var(--on-accent);
  font: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  line-height: 1.4;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 150ms ease-out;
}

.btn:not(:disabled):hover {
  background: var(--accent-hover);
}

.btn:not(:disabled):active {
  transform: translateY(1px);
}

.btn:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

.btn.plain {
  background: var(--sunk);
  color: var(--text);
}

.btn.plain:not(:disabled):hover {
  background: var(--sunk-hover);
}

.btn.danger {
  background: var(--alert);
  color: var(--on-alert);
}

.btn.danger:not(:disabled):hover {
  background: var(--alert-hover);
}

/* ---- the settings: the owner's form, in groups, and each app's configuration, read only */

/* The form, and what the page says of it, stand in a column that a form reads well in. The apps' configuration takes
   the page's width, so that the lines of the help notes, which their file breaks at about 120 characters, fit whole
   where the page is wide enough. */
.settings > h1,
.settings > .notice,
.settings > .error,
.settings-form {
  max-width: 48rem;
}

.settings-form {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

/* A fieldset is as wide as its widest content unless it may be narrower, which would run past a phone's screen. */
.settings fieldset {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.settings legend {
  margin-bottom: 0.25rem;
  padding: 0;
  font-size: 1.1rem;
  font-weight: 600;
}

/* A number needs a short field, an address or a name a longer one; neither is wider than the page. */
.field input.short {
  max-width: 9rem;
}

.field input.long {
  max-width: 32rem;
}

.error ul {
  margin: 0.3rem 0 0;
  padding-left: 1.25rem;
}

.apps {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-top: 1.5rem;
}

.app-config {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
}

/* The help notes of an app, closed until the owner opens them by their summary. */
.app-config summary {
  margin-top: 0.4rem;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
}

.app-config details[open] > summary {
  margin-bottom: 0.5rem;
}

/* The configuration of an app: each term beside its value, and under it where the page is narrow. */
.config {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 0.4rem 1.25rem;
  margin: 0;
  font-size: 0.85rem;
}

.config dt {
  color: var(--text-muted);
}

.config dd {
  max-width: 44rem;
  margin: 0;
}

.config ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* The help notes as their file holds them: their lines kept, and a line longer than the page wrapped, not cut off. The
   box is as wide as the lines, up to the page's width. */
.notes {
  width: fit-content;
  max-width: 100%;
  margin: 0;
  padding: 0.75rem 1rem;
  border-radius: 6px;
  background: var(--inset);
  font: 0.78rem/1.55 var(--mono);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* ---- the login */

.login {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  width: min(24rem, 100% - 2rem);
  margin: 2.5rem auto;
  padding: 1.5rem;
  border: 1px solid var(--border);
  border-radius: 8px;
}

.login .btn {
  align-self: stretch;
  padding-block: 0.55rem;
  font-size: 0.9rem;
}

/* ---- narrower than 640 px: one column */

@media (max-width: 640px) {
  .row {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.4rem;
  }

  .act {
    grid-template-columns: minmax(0, 1fr);
  }

  .config {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.1rem;
  }

  .config dd + dt {
    margin-top: 0.5rem;
  }
}
