/* The Dix design system. Every value the app draws with is a token defined here - colour, type,
   space, radius, border, shadow, opacity, motion, layering, sizes - and a page's own <style> uses
   these rather than writing values of its own. The one thing a page sets itself is a layout
   dimension that belongs only to it, like the width of one of its columns.

   Phone layouts switch at 760px. A custom property can't sit in a media query, so that number is
   written out wherever a layout changes. */

:root {
  color-scheme: light dark;

  /* ---- colour: surfaces and text ---- */
  --bg: #faf9f7;               /* the page */
  --surface: #ffffff;          /* panels, cards, the sidebar */
  --surface-2: #f2f0ec;        /* the tab bar, quiet fills */
  --ink: #1b1b1a;              /* text */
  --muted: #6d6a65;            /* secondary text */
  --faint: #a19d97;            /* hints, disabled text */
  --line: #e5e2dc;             /* borders, rules */
  --line-strong: #cfcac2;      /* a border that has to be seen */
  --line-faint: #efede8;       /* a rule that only guides the eye, like the calendar's half hours */
  --hover: rgba(128, 128, 128, 0.12);
  --backdrop: rgba(15, 15, 14, 0.38);   /* behind a drawer */
  --scrim: rgba(0, 0, 0, 0.55);         /* over a photo or video, e.g. a play button */

  /* ---- colour: the accent ---- */
  --accent: #2f6f4e;
  --accent-ink: #ffffff;       /* text on the accent */
  --accent-soft: rgba(47, 111, 78, 0.13);
  --accent-faint: rgba(47, 111, 78, 0.05);
  --selected: var(--accent-soft);
  --focus: rgba(47, 111, 78, 0.55);

  /* ---- colour: meaning ---- */
  --ok: #16a34a;
  --ok-soft: rgba(22, 163, 74, 0.12);
  --warn: #c2410c;
  --warn-soft: rgba(194, 65, 12, 0.1);
  --danger: #dc2626;
  --danger-soft: rgba(220, 38, 38, 0.1);
  --info: #2563eb;
  --info-soft: rgba(37, 99, 235, 0.1);
  --on-color: #ffffff;         /* text on any saturated fill */
  --on-light: #1b1b1a;         /* text on a light fill, like a yellow event */

  /* ---- colour: what the records are ---- */
  --tag-newside: linear-gradient(135deg, #7c3aed 0%, #f97316 100%);
  --tag-teachersflow: linear-gradient(135deg, #667eea 0%, #8b5cf6 100%);
  --tag-business: #844bf2;
  --tag-personal: #f97316;
  --tag-transfer: #64748b;
  --cal-agent: var(--accent);  /* time spent with an agent, on the calendar */
  --cal-lesson: #f0eeea;       /* a lesson, set apart from the calendar's page */
  --cal-holiday: #16a34a;      /* a state holiday's name */
  --cal-birthday: #0b6b38;     /* whose birthday - a deeper green, to tell it from a holiday */
  /* An item's colour on the calendar: Google Calendar's own 24, by the names it gives them, in the
     order its picker shows them. */
  --cal-radicchio: #ad1457;
  --cal-cherry-blossom: #d81b60;
  --cal-flamingo: #e67c73;
  --cal-tomato: #d50000;
  --cal-tangerine: #f4511e;
  --cal-pumpkin: #ef6c00;
  --cal-mango: #f09300;
  --cal-banana: #f6bf26;
  --cal-citron: #e4c441;
  --cal-avocado: #c0ca33;
  --cal-pistachio: #7cb342;
  --cal-basil: #0b8043;
  --cal-sage: #33b679;
  --cal-eucalyptus: #009688;
  --cal-peacock: #039be5;
  --cal-cobalt: #4285f4;
  --cal-lavender: #7986cb;
  --cal-blueberry: #3f51b5;
  --cal-wisteria: #b39ddb;
  --cal-amethyst: #9e69af;
  --cal-grape: #8e24aa;
  --cal-cocoa: #795548;
  --cal-graphite: #616161;
  --cal-birch: #a79b8e;

  /* ---- colour: the graph's areas, one per top folder, in turn ---- */
  --graph-1: #2f9e6e;
  --graph-2: #4f7fe0;
  --graph-3: #e0803a;
  --graph-4: #a35ad6;
  --graph-5: #d4a017;
  --graph-6: #d9577e;
  --graph-7: #2aa5b8;
  --graph-8: #8a7d63;
  --graph-9: #6f9b2f;
  --graph-10: #c2513a;

  /* ---- type ---- */
  --font-sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  --font-mono: ui-monospace, "Cascadia Code", "SF Mono", Consolas, monospace;
  --text-2xs: 10.5px;
  --text-xs: 11.5px;
  --text-sm: 12.5px;
  --text-md: 13.5px;
  --text-base: 15px;
  --text-lg: 17px;
  --text-xl: 21px;
  --text-2xl: 26px;
  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;
  --leading-tight: 1.25;
  --leading-snug: 1.4;
  --leading-normal: 1.55;
  --leading-relaxed: 1.7;
  --tracking-wide: 0.03em;
  --tracking-caps: 0.06em;

  /* ---- space ---- */
  --space-1: 2px;
  --space-2: 4px;
  --space-3: 6px;
  --space-4: 8px;
  --space-5: 12px;
  --space-6: 16px;
  --space-7: 20px;
  --space-8: 24px;
  --space-9: 32px;
  --space-10: 48px;

  /* ---- radius ---- */
  --radius-xs: 3px;
  --radius-sm: 6px;
  --radius-md: 9px;
  --radius-lg: 12px;
  --radius-xl: 16px;
  --radius-pill: 999px;
  --radius-round: 50%;

  /* ---- border ---- */
  --border-width: 1px;
  --border-thick: 2px;
  --border: var(--border-width) solid var(--line);
  --border-strong: var(--border-width) solid var(--line-strong);

  /* ---- shadow ---- */
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.05);
  --shadow-sm: 0 2px 6px rgba(0, 0, 0, 0.08);
  --shadow-md: 0 4px 14px rgba(0, 0, 0, 0.12);
  --shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.18);

  /* ---- opacity ---- */
  --opacity-faint: 0.35;
  --opacity-muted: 0.55;
  --opacity-disabled: 0.5;
  --opacity-hover: 0.85;

  /* ---- motion ---- */
  --duration-fast: 100ms;
  --duration: 180ms;
  --duration-slow: 300ms;
  --ease: cubic-bezier(0.2, 0.8, 0.2, 1);

  /* ---- layering ---- */
  --z-below: -1;
  --z-raised: 1;
  --z-sticky: 10;
  --z-backdrop: 35;
  --z-drawer: 40;
  --z-overlay: 50;
  --z-tooltip: 60;

  /* ---- sizes ---- */
  --control-sm: 28px;
  --control-md: 34px;
  --control-lg: 40px;
  --icon-sm: 14px;
  --icon-md: 16px;
  --icon-lg: 20px;
  --page-max: 1280px;           /* every page */
  --page-text: 860px;           /* a column of text to read or write - a note, a file */
  --sidebar-width: 270px;
  --editor-gutter: 46px;        /* the line numbers beside the editor */
  --drawer-width: min(86vw, 320px);
  --tooltip-width: 300px;
  --hour-height: 52px;          /* one hour on the calendar */
  --cal-gutter: 52px;           /* the hours beside the calendar */
  --cal-strip: 14px;            /* the agent-time strip down each day, wide enough for a letter */
  --cal-strip-thin: 5px;        /* the same strip where a day is too narrow for one */
  --card-width: 300px;          /* one of the cards a tab with several views opens on */
  --menu-width: 220px;          /* a Filter menu's panel, at its narrowest */
  --menu-max: 420px;            /* ... and at its widest */
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #16171a;
    --surface: #1e2024;
    --surface-2: #101114;
    --ink: #eceae6;
    --muted: #9b9790;
    --faint: #6a6761;
    --line: #2e3137;
    --line-strong: #444851;
    --line-faint: #25272c;
    --backdrop: rgba(0, 0, 0, 0.55);

    --accent: #4c9b74;
    --accent-ink: #0d0f11;
    --accent-soft: rgba(76, 155, 116, 0.2);
    --accent-faint: rgba(76, 155, 116, 0.07);
    --focus: rgba(76, 155, 116, 0.6);

    --ok: #22c55e;
    --cal-holiday: #4ade80;
    --cal-birthday: #22a55a;
    --cal-lesson: #26292e;
    --ok-soft: rgba(34, 197, 94, 0.15);
    --warn: #f97316;
    --warn-soft: rgba(249, 115, 22, 0.14);
    --danger: #f05252;
    --danger-soft: rgba(240, 82, 82, 0.15);
    --info: #60a5fa;
    --info-soft: rgba(96, 165, 250, 0.15);

    --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.3);
    --shadow-sm: 0 2px 6px rgba(0, 0, 0, 0.35);
    --shadow-md: 0 4px 14px rgba(0, 0, 0, 0.45);
    --shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.55);
  }
}


/* ================================================================ base */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
[hidden] { display: none !important; }

body.dix {
  margin: 0; background: var(--bg); color: var(--ink);
  font-family: var(--font-sans); font-size: var(--text-base); line-height: var(--leading-normal);
  scrollbar-width: thin;
}

h1, h2, h3 { line-height: var(--leading-tight); font-weight: var(--weight-semibold); }
h1 { font-size: var(--text-xl); margin: 0; }
h2 { font-size: var(--text-lg); }
h3 { font-size: var(--text-base); }
a { color: var(--accent); }
button, input, select, textarea { font: inherit; color: inherit; }
::selection { background: var(--accent-soft); }
:focus-visible { outline: var(--border-thick) solid var(--focus); outline-offset: var(--space-1); }

.muted { color: var(--muted); }
.num { font-variant-numeric: tabular-nums; white-space: nowrap; }
.ellipsis { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }


/* ================================================================ the tab bar
   The same bar on every page. On a phone it is Dix on the left and the menu the tabs fold behind
   on the right. */

.dixnav {
  position: relative; z-index: var(--z-overlay);
  display: flex; align-items: center; gap: var(--space-2); flex: none;
  min-height: calc(var(--control-md) + 2 * var(--space-4)); padding: 0 var(--space-6);
  white-space: nowrap; background: var(--surface-2); border-bottom: var(--border);
  font-size: var(--text-md);
}
.dixnav .brand {
  font-weight: var(--weight-semibold); letter-spacing: var(--tracking-caps); text-transform: uppercase;
  font-size: var(--text-xs); color: var(--muted); margin-right: var(--space-5);
}
.dixnav .links { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.dixnav .links a {
  color: var(--ink); text-decoration: none; line-height: var(--leading-normal);
  padding: var(--space-2) var(--space-5); border-radius: var(--radius-pill);
  transition: background var(--duration-fast) var(--ease);
}
.dixnav .links a:hover { background: var(--hover); }
.dixnav .links a[aria-current="page"] { background: var(--ink); color: var(--bg); }
.dixnav .menu { display: none; }
/* Only there when a connection is down, so it is allowed to be the loudest thing in the bar. */
.dixnav a.alert {
  margin-right: var(--space-4); padding: var(--space-2) var(--space-5); border-radius: var(--radius-pill);
  background: var(--accent); color: var(--accent-ink); text-decoration: none;
  font-weight: var(--weight-semibold);
}
.dixnav a.alert:hover { opacity: var(--opacity-hover); }


/* ================================================================ page structure */

/* Every page is the same column, the same distance from the edges. A page that is one big surface
   - the calendar - takes the full width instead. */
.page {
  max-width: var(--page-max); margin: 0 auto;
  padding: var(--space-8) var(--space-8) var(--space-10);
}
.page.full { max-width: none; }
/* A page's bar: no title - the nav already says which page it is. What to look at on the left (a
   period, a search), what to do on the right: a Filter menu, then the one main button. Always the
   same height, so moving between tabs doesn't shift the page. */
.head {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-4) var(--space-5);
  min-height: var(--control-md); margin: 0 0 var(--space-8);
}
.head .actions { margin-left: auto; display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-3); }

/* A section of a page: its small heading, then what it holds - no box around it; space does the
   separating. */
.panel { margin: 0 0 var(--space-10); }
.panel > h2, .label-caps {
  margin: 0 0 var(--space-6); font-size: var(--text-xs); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-caps); text-transform: uppercase; color: var(--muted);
}

.empty { color: var(--muted); font-size: var(--text-md); }

/* A page with several views opens on these: one card per view, its name and a line of what it is,
   the set centred across the page and as far from the top as any page's content. Clicking the
   page's tab again comes back here. */
.hub { display: grid; grid-template-columns: repeat(auto-fit, var(--card-width)); justify-content: center; gap: var(--space-6); }
.card {
  display: grid; gap: var(--space-2); align-content: start; min-height: calc(var(--control-lg) * 3);
  padding: var(--space-7); text-align: left; text-decoration: none; color: var(--ink); cursor: pointer;
  background: var(--surface); border: var(--border); border-radius: var(--radius-lg);
  transition: border-color var(--duration-fast) var(--ease);
}
.card:hover { border-color: var(--accent); }
.card b { font-size: var(--text-lg); font-weight: var(--weight-semibold); }
.card span { color: var(--muted); font-size: var(--text-md); }

/* A button that opens a small panel of what is set now and then - filters, which camera. */
dix-menu { position: relative; display: inline-flex; }
dix-menu .menu-pop {
  position: fixed; z-index: var(--z-overlay); display: grid; gap: var(--space-6);
  width: max-content; min-width: var(--menu-width); max-width: min(var(--menu-max), calc(100vw - 2 * var(--space-5)));
  padding: var(--space-6); background: var(--surface); border: var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}
dix-menu .menu-pop .label-caps { margin: 0 0 var(--space-3); }
dix-menu .menu-pop .chips { display: flex; }
dix-menu .menu-pop .input { width: 100%; }
dix-menu .menu-pop .choices { display: grid; gap: var(--space-1); margin: calc(-1 * var(--space-4)); }
dix-menu .menu-pop .choices .btn { justify-content: flex-start; border-color: transparent; background: none; }
dix-menu .menu-pop .choices .btn:hover { background: var(--hover); }
dix-menu .menu-pop .choices .btn[aria-pressed="true"] { color: var(--accent); font-weight: var(--weight-semibold); }

/* Rendered markdown, for reading rather than editing - a note in Files, a note beside the graph. */
.prose { font-size: var(--text-base); line-height: var(--leading-relaxed); overflow-wrap: anywhere; }
.prose h1, .prose h2, .prose h3 { margin: var(--space-8) 0 var(--space-4); }
.prose h1 { font-size: var(--text-2xl); }
.prose h2 { font-size: var(--text-xl); }
.prose h3 { font-size: var(--text-lg); }
.prose > :first-child { margin-top: 0; }
.prose p, .prose ul, .prose ol, .prose blockquote, .prose pre, .prose table { margin: 0 0 var(--space-6); }
.prose ul, .prose ol { padding-left: var(--space-8); }
.prose li { margin: var(--space-2) 0; }
.prose code {
  background: var(--surface); border: var(--border); border-radius: var(--radius-xs);
  padding: 0 var(--space-2); font-family: var(--font-mono); font-size: var(--text-md);
}
.prose pre { background: var(--surface); border: var(--border); border-radius: var(--radius-md); padding: var(--space-5) var(--space-6); overflow: auto; }
.prose pre code { background: none; border: 0; padding: 0; }
.prose blockquote { border-left: var(--border-thick) solid var(--line-strong); padding-left: var(--space-6); color: var(--muted); }
.prose hr { border: 0; border-top: var(--border); margin: var(--space-8) 0; }
.prose table { border-collapse: collapse; }
.prose th, .prose td { border: var(--border); padding: var(--space-3) var(--space-5); text-align: left; }
.prose img { max-width: 100%; border-radius: var(--radius-md); }
.prose .wl { color: var(--accent); cursor: pointer; }
.prose .wl:hover { text-decoration: underline; }
.prose .wl.ghost { color: var(--muted); }
.note { color: var(--muted); font-size: var(--text-md); line-height: var(--leading-normal); margin: 0; }

.banner {
  border: var(--border-width) solid var(--warn); background: var(--warn-soft);
  border-radius: var(--radius-md); padding: var(--space-5) var(--space-6);
  margin: 0 0 var(--space-6); font-size: var(--text-md);
}
.banner.danger { border-color: var(--danger); background: var(--danger-soft); }
.banner b { display: block; margin-bottom: var(--space-2); }
.banner ul { margin: 0; padding-left: var(--space-7); }


/* ================================================================ controls */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-3);
  min-height: var(--control-md); padding: 0 var(--space-6);
  font-size: var(--text-md); font-weight: var(--weight-medium); white-space: nowrap;
  background: var(--surface); color: var(--ink);
  border: var(--border); border-radius: var(--radius-md); cursor: pointer; text-decoration: none;
  transition: border-color var(--duration-fast) var(--ease), background var(--duration-fast) var(--ease);
}
.btn:hover:not(:disabled) { border-color: var(--line-strong); }
.btn:disabled { opacity: var(--opacity-disabled); cursor: default; }
.btn.primary { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.btn.primary:hover:not(:disabled) { opacity: var(--opacity-hover); }
.btn.ghost { background: none; border-color: transparent; color: var(--muted); }
.btn.ghost:hover:not(:disabled) { background: var(--hover); color: var(--ink); }
.btn.danger { background: var(--danger); color: var(--on-color); border-color: var(--danger); }
.btn.sm { min-height: var(--control-sm); padding: 0 var(--space-5); font-size: var(--text-sm); }
.btn.icon { width: var(--control-md); padding: 0; color: var(--muted); }
.btn.icon.sm { width: var(--control-sm); }
.btn svg { width: var(--icon-md); height: var(--icon-md); }
.btn.primary.icon { color: var(--accent-ink); }
/* An icon from lib/icons.js, in the colour of the text around it. */
.icon { display: inline-flex; flex: none; }
.icon svg { width: var(--icon-md); height: var(--icon-md); }

/* ---- form controls: one look for every input, select, text area and check box ----
   A control sits in a .field - its label above it - and says in its placeholder what goes in it.
   Every one has the same font size, the same height and the same box. */
.input {
  min-height: var(--control-md); padding: 0 var(--space-5);
  font: inherit; font-size: var(--text-md); background: var(--bg); color: var(--ink);
  border: var(--border); border-radius: var(--radius-md);
}
.input:focus { outline: none; border-color: var(--line-strong); }
.input::placeholder { color: var(--faint); opacity: 1; }
.input.full { width: 100%; }
/* A select draws its own arrow, so it looks like the other controls everywhere. */
select.input {
  appearance: none; padding-right: calc(var(--space-5) + var(--space-8)); cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - var(--space-6) - var(--space-3)) 50%, calc(100% - var(--space-6)) 50%;
  background-size: var(--space-3) var(--space-3); background-repeat: no-repeat;
}
/* A check box in a box like the other controls: the whole box is what is clicked. */
.checkfield {
  display: flex; align-items: center; gap: var(--space-4); min-height: var(--control-md); padding: 0 var(--space-5);
  font-size: var(--text-md); background: var(--bg); border: var(--border); border-radius: var(--radius-md); cursor: pointer;
}
.checkfield:hover { border-color: var(--line-strong); }
.checkfield input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.checkfield .box {
  position: relative; flex: none; width: var(--icon-md); height: var(--icon-md);
  border: var(--border-thick) solid var(--line-strong); border-radius: var(--radius-xs);
}
.checkfield input:checked + .box { background: var(--accent); border-color: var(--accent); }
.checkfield input:checked + .box::after {
  content: ""; position: absolute; left: 30%; top: 8%; width: 30%; height: 60%;
  border: solid var(--accent-ink); border-width: 0 var(--border-thick) var(--border-thick) 0; transform: rotate(45deg);
}
.checkfield input:focus-visible + .box { outline: var(--border-thick) solid var(--focus); outline-offset: var(--space-1); }
/* A button whose action is under way: it can't be pressed again until it is done. */
.btn[aria-busy="true"] { cursor: progress; opacity: var(--opacity-hover); }

/* A row of options where exactly one is on: Folder | Gallery, Daily note | Dreams. */
.segmented {
  display: inline-flex; gap: var(--space-1); padding: var(--space-1);
  background: var(--surface); border: var(--border); border-radius: var(--radius-md);
}
.segmented button {
  background: none; border: 0; border-radius: var(--radius-sm); cursor: pointer;
  padding: var(--space-2) var(--space-5); font-size: var(--text-md); color: var(--muted);
}
.segmented button:hover { color: var(--ink); }
.segmented button[aria-pressed="true"] {
  background: var(--bg); color: var(--ink); font-weight: var(--weight-semibold);
}

/* Small toggles: a filter, a layer. */
.chips { display: inline-flex; flex-wrap: wrap; gap: var(--space-2); }
.chip {
  display: inline-flex; align-items: center; gap: var(--space-3);
  min-height: var(--control-sm); padding: 0 var(--space-5);
  font-size: var(--text-sm); color: var(--muted); cursor: pointer;
  background: none; border: var(--border); border-radius: var(--radius-pill);
}
.chip:hover { color: var(--ink); }
.chip[aria-pressed="true"] { color: var(--ink); background: var(--surface); border-color: var(--line-strong); }
.chip.solid[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.chip .dot { width: var(--space-4); height: var(--space-4); border-radius: var(--radius-round); }

/* A labelled field in a form: the label above, the control below. */
.field { display: grid; gap: var(--space-2); min-width: 0; }
.field > span { font-size: var(--text-sm); color: var(--muted); }
.row { display: flex; flex-wrap: wrap; align-items: end; gap: var(--space-4); }
/* Side by side, the same width each - the basis is past any control's padding, so it splits evenly. */
.row > .field, .row > .checkfield { flex: 1 1 var(--space-10); min-width: 0; }
.check { display: inline-flex; align-items: center; gap: var(--space-3); font-size: var(--text-md); cursor: pointer; }
input[type="checkbox"], input[type="radio"] { accent-color: var(--accent); width: var(--icon-md); height: var(--icon-md); margin: 0; }
textarea.input { padding: var(--space-4) var(--space-5); min-height: calc(var(--control-lg) * 2); resize: vertical; line-height: var(--leading-normal); }
.field .link { justify-self: start; font-size: var(--text-sm); }

/* A dialog over the page: one form, its actions along the bottom. `ask` is a short question. */
dialog.sheet {
  width: min(520px, calc(100vw - 2 * var(--space-6))); max-height: calc(100dvh - 2 * var(--space-6));
  padding: 0; border: var(--border); border-radius: var(--radius-lg);
  background: var(--surface); color: var(--ink); box-shadow: var(--shadow-lg);
}
dialog.sheet::backdrop { background: var(--backdrop); }
dialog.sheet form { display: grid; gap: var(--space-6); padding: var(--space-7); }
dialog.sheet .foot { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); }
dialog.sheet .foot .grow { flex: 1; }
dialog.sheet .error { color: var(--danger); font-size: var(--text-sm); margin: 0; }

/* Previous, a label, next - a day, a week or a month: the calendar and the school timetable. */
dix-week-nav { display: inline-flex; align-items: center; gap: var(--space-3); }
dix-week-nav .label { font-size: var(--text-md); color: var(--muted); min-width: 0; }


/* ================================================================ figures */

/* A row of figures - no boxes, just the numbers, each over a line of what it is. */
.tiles {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: var(--space-7); margin: 0 0 var(--space-10);
}
dix-stat { display: block; min-width: 0; }
dix-stat .k {
  font-size: var(--text-xs); color: var(--muted);
  text-transform: uppercase; letter-spacing: var(--tracking-caps);
}
dix-stat .v {
  font-size: var(--text-2xl); font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums; margin-top: var(--space-1); line-height: var(--leading-tight);
}
dix-stat .s { font-size: var(--text-sm); color: var(--muted); }
dix-stat[tone="ok"] .v { color: var(--ok); }
dix-stat[tone="danger"] .v { color: var(--danger); }

.chart { position: relative; }
.chart canvas { display: block; width: 100%; height: 240px; }
/* The one tooltip look: .tooltip is what any title becomes (lib/tooltip.js), .tip the reading a
   chart shows under the pointer. */
.tip, .tooltip {
  pointer-events: none; z-index: var(--z-tooltip);
  background: var(--surface); color: var(--ink); border: var(--border-strong); border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-5); font-size: var(--text-sm); line-height: var(--leading-snug);
  box-shadow: var(--shadow-md);
}
.tip { position: absolute; white-space: nowrap; transform: translate(-50%, calc(-100% - var(--space-5))); }
.tooltip { position: fixed; max-width: var(--tooltip-width); overflow-wrap: break-word; }
.tooltip b { display: block; font-weight: var(--weight-semibold); }
.tooltip b + div { margin-top: var(--space-1); }
.tooltip b ~ div { color: var(--muted); }

.table-wrap { overflow-x: auto; }
table.data { width: 100%; border-collapse: collapse; font-size: var(--text-md); }
table.data th, table.data td {
  text-align: left; padding: var(--space-3) var(--space-4); border-bottom: var(--border); vertical-align: top;
}
table.data th {
  color: var(--muted); font-weight: var(--weight-semibold); font-size: var(--text-xs);
  text-transform: uppercase; letter-spacing: var(--tracking-wide); white-space: nowrap;
}
table.data th button {
  background: none; border: 0; padding: 0; color: inherit; font: inherit; cursor: pointer;
  text-transform: inherit; letter-spacing: inherit;
}
table.data th button:hover { color: var(--ink); }
table.data td.right, table.data th.right { text-align: right; }

/* A category: its colour as a dot, then its name. */
.tag { display: inline-flex; align-items: center; gap: var(--space-3); white-space: nowrap; vertical-align: top; --tag: var(--tag-transfer); }
.tag::before { content: ""; flex: none; width: var(--space-4); height: var(--space-4); border-radius: var(--radius-round); background: var(--tag); }
.tag[data-kind="NewSide"] { --tag: var(--tag-newside); }
.tag[data-kind="TeachersFlow"] { --tag: var(--tag-teachersflow); }
.tag[data-kind="Business"] { --tag: var(--tag-business); }
.tag[data-kind="Personal"] { --tag: var(--tag-personal); }
.tag[data-kind="Transfer"] { --tag: var(--tag-transfer); }

/* A short label that has to be noticed: a cancelled lesson, a substitution. */
.badge {
  display: inline-flex; align-items: center; padding: 0 var(--space-4); border-radius: var(--radius-sm);
  font-size: var(--text-xs); font-weight: var(--weight-semibold); white-space: nowrap;
  line-height: var(--leading-normal); background: var(--hover); color: var(--ink);
}
.badge[data-tone="warn"] { background: var(--warn); color: var(--on-color); }
.badge[data-tone="danger"] { background: var(--danger); color: var(--on-color); }
.badge[data-tone="info"] { background: var(--info); color: var(--on-color); }
.badge[data-tone="accent"] { background: var(--accent); color: var(--accent-ink); }

.pos { color: var(--ok); font-weight: var(--weight-semibold); }
.neg { color: var(--danger); font-weight: var(--weight-semibold); }


/* ================================================================ phone */

@media (max-width: 760px) {
  .dixnav { padding: 0 var(--space-4); gap: var(--space-3); }
  /* Dix on the left, the menu on the right. */
  /* The bar's own colour, open or not - a tap leaves no box behind it. */
  .dixnav .menu, .dixnav .menu:hover:not(:disabled) { display: inline-flex; order: 2; background: none; color: var(--ink); }
  .dixnav .brand { margin-right: auto; }
  .dixnav a.alert { order: 1; margin: 0; }
  .dixnav .links {
    display: none; position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; align-items: stretch; gap: var(--space-1);
    padding: var(--space-4); background: var(--surface-2); border-bottom: var(--border);
    box-shadow: var(--shadow-lg);
  }
  .dixnav.open .links { display: flex; }
  .dixnav .links a { padding: var(--space-4) var(--space-6); border-radius: var(--radius-md); font-size: var(--text-base); }
  .page { padding: var(--space-6) var(--space-5) var(--space-9); }
  .head { margin-bottom: var(--space-6); }
  .panel { margin-bottom: var(--space-9); }
  .hub { grid-template-columns: minmax(0, 1fr); gap: var(--space-4); }
  .card { min-height: 0; padding: var(--space-6); }
  .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-6) var(--space-5); margin-bottom: var(--space-9); }
  .tiles > :last-child:nth-child(odd) { grid-column: 1 / -1; }   /* an odd one out takes the row */
  dix-stat .v { font-size: var(--text-xl); }
  dialog.sheet { width: 100vw; max-width: 100vw; height: 100dvh; max-height: 100dvh; margin: 0; border-radius: 0; border: 0; }
  dialog.sheet form { padding: var(--space-6) var(--space-5); }
  /* A short question rises from the bottom instead, its answers one under another, the main one on top. */
  dialog.sheet.ask { height: fit-content; margin: auto 0 0; border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
  dialog.sheet.ask .foot { flex-direction: column-reverse; align-items: stretch; }
  dialog.sheet.ask .foot .grow { display: none; }
}
