/* Affinitas design system 1.1.0 — tokens.css
   Generated from DESIGN.md by `npm run build`. Do not edit by hand. */
:root {
  color-scheme: light;

  /* colour */
  --primary: #0a1f3c;
  --on-primary: #ffffff;
  --navy-950: #061428;
  --navy-900: #0a1f3c;
  --navy-800: #102c52;
  --navy-700: #1b3f6e;
  --navy-100: #e7ecf4;
  --navy-50: #f3f6fb;
  --grey-400: #b9bfc9;
  --grey-600: #6b7482;
  --grey-800: #333b47;
  --accent: #2563eb;
  --accent-dark: #1d4ed8;
  --success: #128b5f;
  --success-soft: #e6f5ee;
  --success-text: #0c6244;
  --success-border: #bfe3d3;
  --success-on-navy: #8fe0bd;
  --gold: #b07d1a;
  --gold-soft: #fbf1dd;
  --danger: #c0392b;
  --danger-soft: #fdecea;
  --danger-text: #8f2a1e;
  --danger-border: #f2c7c2;
  --surface: #ffffff;
  --canvas: #f6f8fc;
  --border: #e2e8f0;
  --brand-navy: #0a1f3c;

  /* radius */
  --radius-xs: 4px;
  --radius-sm: 8px;
  --radius: 14px;
  --radius-lg: 22px;
  --radius-pill: 999px;

  /* spacing */
  --space-xs: 4px;
  --space-sm: 8px;
  --space-md: 12px;
  --space-lg: 16px;
  --space-xl: 20px;
  --space-2xl: 28px;
  --space-3xl: 48px;

  /* type */
  --font-serif: 'Lora', Georgia, 'Times New Roman', serif;
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;

  /* elevation */
  --shadow-sm: 0 1px 2px rgba(10, 31, 60, 0.06);
  --shadow: 0 6px 20px rgba(10, 31, 60, 0.08);
  --shadow-lg: 0 22px 48px rgba(10, 31, 60, 0.16);
  --shadow-bar: 0 -2px 12px rgba(10, 31, 60, 0.05);

  /* fixed sizes */
  --header-height: 64px;
  --tabbar-height: 64px;
  --container-max: 1180px;
}

/* Dark theme. Follows the operating system unless the user picked a theme, which
   js/affinitas.js stores in the `ae-theme` cookie and writes to <html data-theme>. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    color-scheme: dark;
    --primary: #e8eef7;
    --on-primary: #0a1f3c;
    --navy-900: #e8eef7;
    --navy-800: #c9d6e8;
    --navy-700: #8fa6c8;
    --navy-100: #1f3252;
    --navy-50: #172741;
    --grey-400: #56627a;
    --grey-600: #9aa6b8;
    --grey-800: #c3ccd9;
    --accent: #6aa5ff;
    --accent-dark: #9cc3ff;
    --success: #3cc48f;
    --success-soft: #0e2e24;
    --success-text: #93e3c1;
    --success-border: #1e5642;
    --success-on-navy: #0c6244;
    --gold: #e3b04b;
    --gold-soft: #33270f;
    --danger: #f2786d;
    --danger-soft: #3b1815;
    --danger-text: #f7b8b1;
    --danger-border: #6e2c26;
    --surface: #111d30;
    --canvas: #0b1422;
    --border: #243550;
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
    --shadow-lg: 0 22px 48px rgba(0, 0, 0, 0.55);
    --shadow-bar: 0 -2px 12px rgba(0, 0, 0, 0.3);
  }
}

:root[data-theme='dark'] {
  color-scheme: dark;
  --primary: #e8eef7;
  --on-primary: #0a1f3c;
  --navy-900: #e8eef7;
  --navy-800: #c9d6e8;
  --navy-700: #8fa6c8;
  --navy-100: #1f3252;
  --navy-50: #172741;
  --grey-400: #56627a;
  --grey-600: #9aa6b8;
  --grey-800: #c3ccd9;
  --accent: #6aa5ff;
  --accent-dark: #9cc3ff;
  --success: #3cc48f;
  --success-soft: #0e2e24;
  --success-text: #93e3c1;
  --success-border: #1e5642;
  --success-on-navy: #0c6244;
  --gold: #e3b04b;
  --gold-soft: #33270f;
  --danger: #f2786d;
  --danger-soft: #3b1815;
  --danger-text: #f7b8b1;
  --danger-border: #6e2c26;
  --surface: #111d30;
  --canvas: #0b1422;
  --border: #243550;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
  --shadow-lg: 0 22px 48px rgba(0, 0, 0, 0.55);
  --shadow-bar: 0 -2px 12px rgba(0, 0, 0, 0.3);
}

/* ==================================================================
   Affinitas design system — components.css
   Base styles and every component. Needs tokens.css (generated from
   DESIGN.md) loaded before it; affinitas.css bundles the two.
   ================================================================== */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

/* The page never shifts sideways when it starts or stops overflowing. With js/affinitas.js the
   browser's scrollbar is hidden and an overlay thumb is drawn instead (see "scrollbar" below);
   without it, the gutter is reserved so the layout stays put. */
html {
  scrollbar-gutter: stable;
}

html.ae-scrollbar-page {
  scrollbar-gutter: auto;
  scrollbar-width: none;
}

html.ae-scrollbar-page::-webkit-scrollbar {
  display: none;
}

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.55;
  color: var(--navy-900);
  background: var(--canvas);
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3,
h4 {
  margin: 0;
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.2;
}

h1 {
  font-family: var(--font-serif);
  font-size: 1.6rem;
}

p {
  margin: 0;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  cursor: pointer;
}

img {
  max-width: 100%;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}

/* --------------------------------------------------- layout helpers */
.container {
  width: 100%;
  max-width: var(--container-max);
  margin: 0 auto;
  padding-inline: 16px;
}

.stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
}

/* --------------------------------------------------- spacing primitives
   Space between siblings belongs to their parent, never to the siblings: wrap a group in one of
   these instead of adding margins. Every step is a spacing token. See DESIGN.md § Layout,
   "Spacing between elements". */
.stack--xs {
  gap: var(--space-xs);
}

.stack--sm {
  gap: var(--space-sm);
}

.stack--md {
  gap: var(--space-md);
}

.stack--lg {
  gap: var(--space-lg);
}

.stack--2xl {
  gap: var(--space-2xl);
}

.stack--3xl {
  gap: var(--space-3xl);
}

/* Items side by side that wrap when there is no room: pills, chips, meta, small controls. */
.cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
}

.cluster--md {
  gap: var(--space-md);
}

.cluster--lg {
  gap: var(--space-lg);
}

/* A row of buttons. Right-aligned by default, as in dialogs and sheet footers. */
.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-sm);
}

.actions--start {
  justify-content: flex-start;
}

.actions--between {
  justify-content: space-between;
}

/* On a phone the buttons stack full width, the primary one on top. */
@media (max-width: 479px) {
  .actions--stack {
    flex-direction: column-reverse;
    align-items: stretch;
  }
}

/* Inside a primitive the gap is the only space: components that carry an outer margin of
   their own when they stand alone drop it. */
:is(.stack, .cluster, .actions) > :is(.page-head, .section-title, .chips, .toolbar, .datestrip, .compact-list, .tasks, .pill) {
  margin: 0;
}

/* Running content (paragraphs, a list, a note, a button) inside a card or a panel. */
.flow > * + * {
  margin-block-start: var(--space-md);
}

.flow--sm > * + * {
  margin-block-start: var(--space-sm);
}

.flow--lg > * + * {
  margin-block-start: var(--space-xl);
}

.muted {
  color: var(--grey-600);
}

.eyebrow {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--grey-600);
}

.page-head {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 18px;
}

/* Main column plus a 306px side panel from 1020px. */
.split {
  display: grid;
  gap: 20px;
}

.panel__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 14px;
}

.panel__title {
  font-size: 1.05rem;
}

.panel__sub {
  font-size: 0.82rem;
}

.section-title {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}

.section-title a {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--accent);
}

.section-title__text {
  font-size: 1.05rem;
}

/* --------------------------------------------------- brand mark */
.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.brand__logo {
  width: 38px;
  height: 38px;
  border-radius: 10px;
  object-fit: contain;
  background: #fff;
  padding: 2px;
  box-shadow: var(--shadow-sm);
}

.brand__text {
  display: flex;
  flex-direction: column;
  line-height: 1.05;
}

.brand__name {
  font-family: var(--font-serif);
  font-size: 1.02rem;
  font-weight: 600;
}

.brand__sub {
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--grey-600);
}

.brand--inverse .brand__sub {
  color: rgba(255, 255, 255, 0.66);
}

/* --------------------------------------------------- buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 46px;
  padding: 0 18px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: var(--navy-900);
  color: var(--on-primary);
  font-weight: 600;
  font-size: 0.94rem;
  transition:
    transform 0.12s ease,
    background 0.15s ease,
    box-shadow 0.15s ease;
}

.btn:hover:not(:disabled) {
  background: var(--navy-800);
  box-shadow: var(--shadow);
}

.btn:active:not(:disabled) {
  transform: translateY(1px);
}

.btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.btn--block {
  width: 100%;
}

.btn--ghost {
  background: transparent;
  color: var(--navy-900);
  border-color: var(--border);
}

.btn--ghost:hover:not(:disabled) {
  background: var(--navy-50);
  box-shadow: none;
}

.btn--sso {
  background: var(--surface);
  color: var(--navy-900);
  border-color: var(--border);
}

.btn--sso:hover:not(:disabled) {
  background: var(--navy-50);
}

.btn--danger {
  background: transparent;
  color: var(--danger);
  border-color: var(--danger-border);
  min-height: 38px;
  font-size: 0.85rem;
}

.btn--danger:hover:not(:disabled) {
  background: var(--danger-soft);
  box-shadow: none;
}

.btn--icon {
  min-height: 40px;
  width: 40px;
  padding: 0;
  background: var(--surface);
  color: var(--navy-900);
  border-color: var(--border);
  font-size: 1.1rem;
}

.btn--icon:hover:not(:disabled) {
  background: var(--navy-50);
  box-shadow: none;
}

.btn--sm {
  min-height: 38px;
  padding-inline: 16px;
  font-size: 0.84rem;
}

.link-button {
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent);
  font-size: 0.8rem;
  font-weight: 700;
  text-align: left;
}

.link-button:disabled {
  color: var(--grey-400);
  cursor: not-allowed;
}

/* --------------------------------------------------- segmented control, chips, tabs */
.segmented {
  display: inline-flex;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--surface);
}

.segmented button {
  padding: 7px 16px;
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--grey-600);
  font-size: 0.84rem;
  font-weight: 600;
  transition: background 0.15s ease, color 0.15s ease;
}

.segmented button.is-active {
  background: var(--navy-900);
  color: var(--on-primary);
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 12px;
}

.chips button {
  padding: 6px 13px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: var(--grey-600);
  font-size: 0.8rem;
  font-weight: 600;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.chips button.is-on {
  background: var(--navy-900);
  border-color: var(--navy-900);
  color: var(--on-primary);
}

/* Underline tabs, for sections inside one page. */
.tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--border);
}

.tabs__tab {
  padding: 10px 16px;
  border: 0;
  background: transparent;
  font-weight: 600;
  color: var(--grey-600);
  border-bottom: 2px solid transparent;
}

.tabs__tab.is-active {
  color: var(--navy-900);
  border-bottom-color: var(--accent);
}

/* --------------------------------------------------- cards & forms */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: 20px;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.field label,
.field__label {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--grey-800);
}

.field input,
.field select {
  min-height: 46px;
  padding: 0 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font: inherit;
  color: inherit;
}

.field input:focus,
.field select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 15%, transparent);
}

.field__hint {
  font-size: 0.72rem;
  color: var(--grey-600);
}

.weekday-picker {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 6px;
}

.weekday-picker button {
  min-height: 44px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--grey-600);
  font-size: 0.8rem;
  font-weight: 700;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.weekday-picker button.is-on {
  background: var(--navy-900);
  border-color: var(--navy-900);
  color: var(--on-primary);
}

.alert {
  padding: 11px 14px;
  border-radius: var(--radius-sm);
  font-size: 0.88rem;
  border: 1px solid transparent;
}

.alert--error {
  background: var(--danger-soft);
  border-color: var(--danger-border);
  color: var(--danger-text);
}

.alert--info {
  background: var(--navy-50);
  border-color: var(--navy-100);
  color: var(--navy-800);
}

.alert--success {
  background: var(--success-soft);
  border-color: var(--success-border);
  color: var(--success-text);
}

.note {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.8rem;
  color: var(--grey-600);
}

.note__mark {
  flex: none;
  color: var(--navy-700);
}

.divider {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--grey-600);
  font-size: 0.76rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.divider::before,
.divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--border);
}

.spinner {
  width: 22px;
  height: 22px;
  border: 2.5px solid var(--navy-100);
  border-top-color: var(--navy-900);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}

.spinner--center {
  margin: 48px auto;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

.empty {
  padding: 26px 16px;
  text-align: center;
  color: var(--grey-600);
  font-size: 0.88rem;
  border: 1px dashed var(--border);
  border-radius: var(--radius);
}

.placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 48px 20px;
  text-align: center;
  border: 1px dashed var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
}

.placeholder__body {
  max-width: 46ch;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}

/* --------------------------------------------------- language switcher */
.langswitch {
  display: inline-flex;
  gap: 4px;
}

.langswitch button {
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--grey-600);
  font-weight: 600;
  transition:
    background 0.15s ease,
    color 0.15s ease,
    border-color 0.15s ease;
}

.langswitch button.is-active {
  background: var(--navy-900);
  border-color: var(--navy-900);
  color: var(--on-primary);
}

.langswitch--pill {
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--surface);
}

.langswitch--pill button {
  padding: 6px 14px;
  border: 0;
  border-radius: var(--radius-pill);
  font-size: 0.8rem;
}

.langswitch--inline {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
}

.langswitch--inline button {
  min-height: 38px;
  border-radius: var(--radius-sm);
  font-size: 0.84rem;
}

/* --------------------------------------------------- theme switch
   System, light or dark. Each button carries `data-theme-set`; js/affinitas.js stores the
   choice in a cookie and marks the current one `.is-active` and `aria-pressed`. The pill is
   icons only (sign-in top bar), the inline variant sits in the account menu. */
.themeswitch {
  display: inline-flex;
  gap: 4px;
}

.themeswitch button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--grey-600);
  font-weight: 600;
  transition:
    background 0.15s ease,
    color 0.15s ease,
    border-color 0.15s ease;
}

.themeswitch button:hover:not(.is-active) {
  color: var(--navy-900);
}

.themeswitch button.is-active {
  background: var(--navy-900);
  border-color: var(--navy-900);
  color: var(--on-primary);
}

.themeswitch--pill {
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--surface);
}

.themeswitch--pill button {
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-pill);
}

.themeswitch--inline {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
}

.themeswitch--inline button {
  flex-direction: column;
  gap: 3px;
  min-height: 52px;
  padding: 6px 4px;
  border-radius: var(--radius-sm);
  font-size: 0.74rem;
}

/* --------------------------------------------------- pills & badges */
.pill {
  align-self: flex-start;
  margin-top: 8px;
  padding: 3px 9px;
  border-radius: var(--radius-pill);
  background: var(--navy-50);
  color: var(--grey-600);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 9px;
  border-radius: var(--radius-pill);
  background: var(--gold-soft);
  color: var(--gold);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* --------------------------------------------------- app shell */
.shell {
  display: flex;
  flex-direction: column;
  min-height: 100%;
}

.shell__header {
  position: sticky;
  top: 0;
  z-index: 20;
  height: var(--header-height);
  display: flex;
  align-items: center;
  background: var(--surface);
  background: color-mix(in srgb, var(--surface) 90%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}

.shell__header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.shell__nav {
  display: none;
  gap: 4px;
}

.shell__nav a {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 13px;
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--grey-600);
  transition: background 0.15s ease, color 0.15s ease;
}

.shell__nav a:hover {
  background: var(--navy-50);
  color: var(--navy-900);
}

.shell__nav a.is-active {
  background: var(--navy-900);
  color: var(--on-primary);
}

.account {
  position: relative;
}

.account__trigger {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 5px 8px 5px 5px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  background: transparent;
  color: inherit;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.account__trigger:hover,
.account__trigger[aria-expanded='true'] {
  background: var(--navy-50);
  border-color: var(--border);
}

.account__meta {
  display: none;
  flex-direction: column;
  align-items: flex-start;
  line-height: 1.15;
  text-align: left;
}

.account__name {
  font-size: 0.86rem;
  font-weight: 600;
}

.account__mail {
  font-size: 0.72rem;
  color: var(--grey-600);
}

.account__caret {
  display: none;
  color: var(--grey-600);
  transition: transform 0.15s ease;
}

.account__caret.is-open {
  transform: rotate(180deg);
}

.account__menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 40;
  width: 250px;
  padding: 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow-lg);
}

.account__header {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  overflow-wrap: anywhere;
}

.account__section {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px;
  border-bottom: 1px solid var(--border);
}

.account__section-label {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--grey-600);
}

.account__link {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  margin-top: 6px;
  padding: 11px 12px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--navy-800);
  font-size: 0.9rem;
  font-weight: 600;
  text-align: left;
  text-decoration: none;
  transition: background 0.15s ease;
}

.account__link:hover {
  background: var(--navy-50);
}

.account__signout {
  width: 100%;
  margin-top: 6px;
  padding: 11px 12px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--danger);
  font-size: 0.9rem;
  font-weight: 600;
  text-align: left;
  transition: background 0.15s ease;
}

.account__signout:hover {
  background: var(--danger-soft);
}

.shell__main {
  flex: 1;
  padding-block: 22px calc(var(--tabbar-height) + 28px);
}

/* Mobile-first: primary navigation lives in a thumb-reachable tab bar. The active tab is
   marked three ways over — a filled pill behind the icon, a heavier stroke and a navy label —
   because on a phone in daylight one signal is not enough. */
.tabbar {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 30;
  display: flex;
  justify-content: space-around;
  gap: 2px;
  padding: 6px 8px calc(6px + env(safe-area-inset-bottom));
  background: var(--surface);
  background: color-mix(in srgb, var(--surface) 94%, transparent);
  backdrop-filter: blur(12px);
  border-top: 1px solid var(--border);
  box-shadow: var(--shadow-bar);
}

.tabbar__tab {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  min-height: 52px;
  padding: 4px 2px;
  border-radius: var(--radius);
  color: var(--grey-600);
  -webkit-tap-highlight-color: transparent;
}

.tabbar__pill {
  display: grid;
  place-items: center;
  width: 56px;
  height: 30px;
  border-radius: var(--radius-pill);
  background: transparent;
  transition:
    background 0.18s ease,
    color 0.18s ease,
    transform 0.18s ease;
}

.tabbar__label {
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
  transition: color 0.18s ease;
}

@media (max-width: 360px) {
  .tabbar {
    padding-inline: 4px;
  }

  .tabbar__pill {
    width: 50px;
  }

  .tabbar__label {
    font-size: 0.62rem;
  }
}

.tabbar__tab.is-active {
  color: var(--navy-900);
}

.tabbar__tab.is-active .tabbar__pill {
  background: var(--navy-100);
  color: var(--navy-900);
}

.tabbar__tab.is-active .tabbar__label {
  font-weight: 700;
}

.tabbar__tab:active .tabbar__pill {
  transform: scale(0.92);
}

.tabbar__tab:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

@media (min-width: 860px) {
  .shell__nav,
  .account__meta {
    display: flex;
  }

  .account__caret {
    display: block;
  }

  .tabbar {
    display: none;
  }

  .shell__main {
    padding-block: 32px 56px;
  }
}

/* --------------------------------------------------- blocking dialog */
.dialog {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.dialog__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(6, 20, 40, 0.55);
  backdrop-filter: blur(2px);
}

.dialog__panel {
  position: relative;
  width: 100%;
  max-width: 440px;
  padding: 22px;
  border-radius: var(--radius-lg);
  border-top: 4px solid var(--gold);
  background: var(--surface);
  box-shadow: var(--shadow-lg);
}

.dialog__panel--error {
  border-top-color: var(--danger);
}

.dialog__panel:focus {
  outline: none;
}

.dialog__title {
  font-family: var(--font-serif);
  font-size: 1.2rem;
  margin-bottom: 10px;
}

.dialog__body {
  font-size: 0.92rem;
  line-height: 1.55;
  color: var(--grey-800);
}

.dialog__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 20px;
}

.dialog__actions .btn {
  flex: 1 1 auto;
}

@media (min-width: 480px) {
  .dialog__actions .btn {
    flex: 0 0 auto;
  }
}

/* --------------------------------------------------- bottom sheet / modal */
.sheet {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.sheet__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(6, 20, 40, 0.55);
  backdrop-filter: blur(2px);
}

.sheet__panel {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-height: 92vh;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  background: var(--canvas);
  box-shadow: var(--shadow-lg);
}

.sheet__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 18px 12px;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}

.sheet__head h2 {
  font-family: var(--font-serif);
  font-size: 1.25rem;
}

.sheet__body {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 18px;
  overflow-y: auto;
}

.sheet__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 14px 18px;
  padding-bottom: calc(14px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--border);
  background: var(--surface);
}

@media (min-width: 700px) {
  .sheet {
    align-items: center;
    padding: 24px;
  }

  .sheet__panel {
    max-width: 680px;
    border-radius: var(--radius-lg);
  }
}

/* --------------------------------------------------- avatars & people */
.avatar {
  position: relative;
  display: grid;
  place-items: center;
  flex: none;
  overflow: hidden;
  border-radius: 50%;
  background: var(--navy-900);
  color: var(--on-primary);
  font-weight: 700;
  object-fit: cover;
}

/* The signed-in user's account photo (Google `picture`, Microsoft Graph photo) over the
   initials. The initials stay underneath: they show while it loads and, because
   js/affinitas.js marks a failed image `data-broken`, when it does not. */
.avatar__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
}

.avatar__img[data-broken] {
  display: none;
}

.avatar--sm {
  width: 26px;
  height: 26px;
  font-size: 0.64rem;
}

.avatar--md {
  width: 38px;
  height: 38px;
  font-size: 0.8rem;
}

.avatar--lg {
  width: 48px;
  height: 48px;
  font-size: 0.95rem;
}

.profile {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  width: 244px;
  padding: 13px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow-lg);
  text-align: left;
}

.profile__text {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.profile__name {
  font-size: 0.9rem;
  font-weight: 700;
  overflow-wrap: anywhere;
}

.profile__you {
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: var(--radius-pill);
  background: var(--navy-50);
  color: var(--grey-600);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.profile__role {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--grey-800);
}

.profile__dept {
  font-size: 0.74rem;
  color: var(--grey-600);
}

.profile__mail {
  margin-top: 4px;
  font-size: 0.74rem;
  color: var(--accent);
  overflow-wrap: anywhere;
}

.profile__mail:hover {
  text-decoration: underline;
}

/* Hover or keyboard focus reveals the card. */
.profile-anchor {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border-radius: var(--radius-sm);
  cursor: default;
}

.profile-anchor__card {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 0;
  z-index: 25;
  opacity: 0;
  visibility: hidden;
  transform: translateY(4px);
  transition:
    opacity 0.12s ease,
    transform 0.12s ease,
    visibility 0.12s;
}

.profile-anchor:hover .profile-anchor__card,
.profile-anchor:focus-visible .profile-anchor__card,
.profile-anchor:focus-within .profile-anchor__card {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

/* --------------------------------------------------- sign-in
   A full-screen layer of its own. It is fixed to the viewport, so no wrapper (an app root, a
   .container, a .shell) can shrink it, cut it off or pin it to the top, and it is its own scroll
   area when a small phone cannot fit the form. The form is centred with auto margins rather than
   `justify-content: center`, which would cut off the top of a form taller than the screen.
   Markup: DESIGN.md § Components, "Sign-in". */
.signin {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--canvas);
  color: var(--navy-900);
}

.signin__aside {
  display: none;
}

.signin__panel {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: 20px 20px 48px;
}

.signin__topbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-sm);
  margin-bottom: 18px;
}

.signin__inner {
  width: 100%;
  max-width: 400px;
  margin: auto;
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.signin__mark {
  margin-bottom: 20px;
}

.signin__aside-foot {
  position: relative;
  font-size: 0.78rem;
  color: rgba(255, 255, 255, 0.55);
}

.signin__heading h1 {
  font-size: 1.75rem;
  margin-bottom: 6px;
}

.signin__form {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.signin__sso {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.signin__sso-note {
  margin-top: 6px;
  font-size: 0.78rem;
  color: var(--grey-600);
  padding-left: 2px;
}

.signin__footer {
  font-size: 0.78rem;
  color: var(--grey-600);
  text-align: center;
}

/* The navy panel: one of the two gradients in the system. Navy in both themes. It stays the
   full height of the screen while the form scrolls, with the mark at the top, the quote centred
   in the space between and the copyright at the bottom, whatever else it holds. */
@media (min-width: 900px) {
  .signin {
    grid-template-columns: 1.05fr 1fr;
  }

  .signin__aside {
    position: sticky;
    top: 0;
    display: grid;
    grid-template-rows: auto minmax(0, 1fr) auto;
    gap: var(--space-2xl);
    height: 100vh;
    height: 100dvh;
    padding: 44px;
    color: #fff;
    background:
      radial-gradient(120% 90% at 12% 8%, rgba(37, 99, 235, 0.42), transparent 58%),
      radial-gradient(90% 70% at 92% 96%, rgba(18, 139, 95, 0.3), transparent 60%),
      linear-gradient(155deg, var(--brand-navy), var(--navy-950));
    overflow: hidden;
  }

  .signin__aside > * {
    grid-row: 1;
    justify-self: start;
  }

  .signin__aside::after {
    content: '';
    position: absolute;
    inset: auto -120px -180px auto;
    width: 460px;
    height: 460px;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 50%;
  }

  .signin__quote {
    position: relative;
    grid-row: 2;
    align-self: center;
    max-width: 460px;
  }

  .signin__aside > .signin__aside-foot {
    grid-row: 3;
  }

  .signin__quote h2 {
    font-family: var(--font-serif);
    font-size: 2.35rem;
    line-height: 1.16;
    margin-bottom: 14px;
  }

  .signin__quote p {
    color: rgba(255, 255, 255, 0.74);
    font-size: 1rem;
  }

  /* The navy panel carries the mark and the copyright line, so the form drops both. */
  .signin__mark,
  .signin__footer {
    display: none;
  }

  .signin__panel {
    padding-block: 20px 32px;
  }
}

/* --------------------------------------------------- hero & tiles */
.hero {
  position: relative;
  overflow: hidden;
  padding: 26px 22px;
  border-radius: var(--radius-lg);
  color: #fff;
  background:
    radial-gradient(110% 120% at 8% 0%, rgba(37, 99, 235, 0.4), transparent 60%),
    linear-gradient(150deg, var(--brand-navy), var(--navy-950));
  box-shadow: var(--shadow);
}

.hero::after {
  content: '';
  position: absolute;
  inset: -60px -80px auto auto;
  width: 240px;
  height: 240px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 50%;
}

.hero h1 {
  position: relative;
  font-size: 1.65rem;
  margin-bottom: 6px;
}

.hero p {
  position: relative;
  color: rgba(255, 255, 255, 0.76);
  max-width: 52ch;
}

.hero__eyebrow {
  position: relative;
  display: block;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.6);
  margin-bottom: 8px;
}

.hero__cta {
  position: relative;
  display: inline-flex;
  margin-top: 18px;
  background: #fff;
  color: var(--brand-navy);
}

/* The hero is navy in both themes, so its button keeps its colours in both. */
.hero__cta:hover:not(:disabled) {
  background: color-mix(in srgb, #fff 90%, var(--brand-navy));
}

.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 14px;
}

.tile {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  text-align: left;
  transition:
    transform 0.12s ease,
    box-shadow 0.15s ease,
    border-color 0.15s ease;
}

a.tile:hover {
  transform: translateY(-2px);
  border-color: var(--navy-700);
  box-shadow: var(--shadow);
}

.tile--soon {
  opacity: 0.62;
  cursor: not-allowed;
}

.tile__icon {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
  color: var(--navy-800);
}

.tile--soon .tile__icon {
  color: var(--grey-600);
}

.tile--stat .tile__icon {
  margin-bottom: 4px;
  color: var(--accent);
}

.tile__title {
  font-weight: 600;
  font-size: 0.98rem;
}

.tile__body {
  font-size: 0.82rem;
  color: var(--grey-600);
}

.tile__metric {
  font-family: var(--font-serif);
  font-size: 2rem;
  font-weight: 600;
  line-height: 1.05;
}

/* --------------------------------------------------- toolbar & week navigation */
.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 16px;
}

.toolbar__spacer {
  flex: 1;
}

.toolbar select {
  min-height: 42px;
  padding: 0 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font: inherit;
  font-weight: 600;
}

.week-nav {
  display: flex;
  align-items: center;
  gap: 8px;
}

.week-nav__label {
  min-width: 168px;
  text-align: center;
  font-size: 0.88rem;
  font-weight: 600;
}

/* --------------------------------------------------- date strip */
.datestrip {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 8px;
  margin-bottom: 20px;
}

.date {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 10px 4px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--navy-900);
  transition:
    border-color 0.15s ease,
    background 0.15s ease,
    box-shadow 0.15s ease;
}

.date:hover:not(:disabled) {
  border-color: var(--navy-700);
}

.date.is-selected {
  background: var(--navy-900);
  border-color: var(--navy-900);
  color: var(--on-primary);
  box-shadow: var(--shadow);
}

.date:disabled {
  opacity: 0.42;
  cursor: not-allowed;
  background: var(--navy-50);
}

.date__weekday {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.72;
}

.date__number {
  font-size: 1.25rem;
  font-weight: 700;
  line-height: 1.1;
}

/* Load at a glance: how full the day already is. */
.date__bar {
  display: block;
  width: 68%;
  height: 4px;
  border-radius: var(--radius-pill);
  background: var(--navy-100);
  overflow: hidden;
}

.date.is-selected .date__bar {
  background: color-mix(in srgb, var(--on-primary) 24%, transparent);
}

.date__bar i {
  display: block;
  height: 100%;
  border-radius: var(--radius-pill);
  background: var(--gold);
}

.date__caption {
  font-size: 0.66rem;
  font-weight: 600;
  opacity: 0.78;
}

.date__note {
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--success);
}

.date.is-selected .date__note {
  color: var(--success-on-navy);
}

/* --------------------------------------------------- list rows */
.rows {
  display: grid;
  grid-template-columns: 1fr;
  gap: 8px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.list-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 10px 12px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--grey-400);
  border-radius: var(--radius);
  background: var(--surface);
}

.list-row--success {
  border-left-color: var(--success);
}

.list-row--selected {
  border-left-color: var(--navy-900);
  background: var(--navy-50);
}

.list-row--attention {
  border-left-color: var(--gold);
}

.list-row--danger {
  border-left-color: var(--danger);
}

.list-row--muted {
  opacity: 0.6;
}

.list-row__main {
  display: flex;
  flex-direction: column;
  line-height: 1.25;
}

.list-row__title {
  font-size: 0.94rem;
  font-weight: 700;
}

.list-row__sub {
  font-size: 0.74rem;
  color: var(--grey-600);
}

.list-row__who {
  display: flex;
  align-items: center;
  gap: 8px;
  grid-column: 1 / -1;
  font-size: 0.84rem;
  order: 3;
}

.list-row__status {
  font-weight: 600;
  color: var(--success);
}

.list-row--attention .list-row__status {
  color: var(--gold);
}

.list-row--danger .list-row__status {
  color: var(--danger);
}

.list-row--muted .list-row__status {
  color: var(--grey-600);
}

.list-row__action {
  min-height: 38px;
  padding-inline: 16px;
  font-size: 0.84rem;
}

/* Compact items inside a side panel. */
.compact-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
}

.compact-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 11px 13px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--navy-50);
}

.compact-item__title {
  font-size: 0.86rem;
  font-weight: 600;
}

.compact-item__sub {
  font-size: 0.75rem;
  color: var(--grey-600);
}

.legend {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  font-size: 0.76rem;
  color: var(--grey-600);
}

.legend span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.legend i {
  width: 9px;
  height: 9px;
  border-radius: 50%;
}

.legend__success {
  background: var(--success);
}

.legend__selected {
  background: var(--navy-900);
}

.legend__neutral {
  background: var(--grey-400);
}

.legend__attention {
  background: var(--gold);
}

.legend__danger {
  background: var(--danger);
}

@media (min-width: 620px) {
  .list-row {
    grid-template-columns: 1fr 1.2fr auto;
  }

  .list-row__who {
    grid-column: auto;
    order: 0;
  }
}

@media (min-width: 720px) {
  .datestrip {
    gap: 12px;
  }

  .date {
    padding: 14px 6px;
  }
}

@media (min-width: 1020px) {
  .split {
    grid-template-columns: minmax(0, 1fr) 306px;
    align-items: start;
  }
}

/* --------------------------------------------------- agenda */
.agenda-day + .agenda-day {
  margin-top: 22px;
}

.agenda-day__title {
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--grey-600);
  margin-bottom: 10px;
}

.agenda-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.event {
  display: flex;
  gap: 14px;
  padding: 13px 15px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}

.event--free {
  border-left-color: var(--grey-400);
}

.event__time {
  display: flex;
  flex-direction: column;
  min-width: 58px;
  font-size: 0.86rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.event__until {
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--grey-600);
}

.event__body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.event__subject {
  font-weight: 600;
  overflow-wrap: anywhere;
}

.event__meta {
  font-size: 0.78rem;
  color: var(--grey-600);
  overflow-wrap: anywhere;
}

.event__link {
  align-self: flex-start;
  margin-top: 4px;
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--accent);
}

.tasks {
  display: flex;
  flex-direction: column;
  gap: 10px;
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
}

.tasks li {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--navy-50);
}

.task__title {
  font-size: 0.88rem;
  font-weight: 600;
}

.task__meta {
  font-size: 0.74rem;
  color: var(--grey-600);
}

/* --------------------------------------------------- scrollbar
   Drawn by js/affinitas.js over the page (between the header and the tab bar) and over
   `.signin`, `.sheet__body` and `[data-scrollbar]` elements, whose own scrollbar is hidden. The
   thumb shows only while the content scrolls, never when it fits, and fades after a moment of
   stillness. It can be dragged while it is visible. */
.ae-scrollbar-host {
  scrollbar-width: none;
}

.ae-scrollbar-host::-webkit-scrollbar {
  display: none;
}

.ae-scrollbar {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 15;
  width: 12px;
  height: 0;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity 0.25s ease,
    visibility 0.25s;
}

.ae-scrollbar.is-visible {
  opacity: 1;
  visibility: visible;
}

.ae-scrollbar__thumb {
  position: absolute;
  top: 0;
  right: 3px;
  width: 6px;
  min-height: 32px;
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--grey-600) 55%, transparent);
  touch-action: none;
  transition:
    width 0.15s ease,
    background 0.15s ease;
}

.ae-scrollbar.is-visible .ae-scrollbar__thumb {
  pointer-events: auto;
}

.ae-scrollbar__thumb:hover,
.ae-scrollbar.is-dragging .ae-scrollbar__thumb {
  width: 8px;
  background: color-mix(in srgb, var(--grey-600) 85%, transparent);
}
