/* Work Tracker — base layout and styles (UI style: docs/SPEC.md 5.5).
   All colors, sizes and spacings are variables in :root; dark mode (TASKS.md 6.4) is a second set of color values,
   following the system unless a theme is chosen (data-theme="light" or "dark" on <html>). */

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/static/fonts/Inter-Regular.woff2') format('woff2');
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/static/fonts/Inter-SemiBold.woff2') format('woff2');
}

:root {
  /* Colors */
  --color-text: #36454f;
  --color-muted: #66737d;
  --color-background: #ffffff;
  --color-surface: #f4f7fb;
  --color-border: #dce4ee;
  --color-accent: #2c69cb;
  --color-accent-light: #e8f0fc;
  --color-warning: #e62e6b;
  --color-warning-text: #c81e57;
  --color-warning-light: #fdecf2;
  --color-positive: #1a7b5e;
  --color-positive-light: #e6f6f0;
  --color-on-accent: #ffffff;

  color-scheme: light;

  /* Typography */
  --font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-size-small: 0.8125rem;
  --font-size-base: 0.9375rem;
  --font-size-large: 1.125rem;
  --font-size-title: 1.5rem;
  --font-weight-normal: 400;
  --font-weight-strong: 600;
  --line-height: 1.5;

  /* Spacing, shapes and layout */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --radius: 6px;
  --border: 1px solid var(--color-border);
  --focus-ring: 0 0 0 3px var(--color-accent-light);
  --content-width: 72rem;
  --header-height: 3.5rem;
  --header-offset: var(--header-height);  /* the header's real height, measured by main.ts (it wraps on narrow screens) */
}

/* Dark mode: the same roles in dark; both blocks hold the same values (kept equal by a test). On screen only: printed
   pages use the light colors. */

@media screen and (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --color-text: #e3e8ee;
    --color-muted: #9aa6b2;
    --color-background: #16191d;
    --color-surface: #1f242a;
    --color-border: #333c46;
    --color-accent: #6ea2f0;
    --color-accent-light: #1e2f48;
    --color-warning: #f06a93;
    --color-warning-text: #ff8fb0;
    --color-warning-light: #3a1f2b;
    --color-positive: #4cc59a;
    --color-positive-light: #173a2f;
    --color-on-accent: #10233f;

    color-scheme: dark;
  }
}

@media screen {
  :root[data-theme='dark'] {
    --color-text: #e3e8ee;
    --color-muted: #9aa6b2;
    --color-background: #16191d;
    --color-surface: #1f242a;
    --color-border: #333c46;
    --color-accent: #6ea2f0;
    --color-accent-light: #1e2f48;
    --color-warning: #f06a93;
    --color-warning-text: #ff8fb0;
    --color-warning-light: #3a1f2b;
    --color-positive: #4cc59a;
    --color-positive-light: #173a2f;
    --color-on-accent: #10233f;

    color-scheme: dark;
  }
}

/* Base */

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

html {
  font-size: 100%;
  -webkit-text-size-adjust: 100%;
  scroll-padding-top: calc(var(--header-offset) + var(--space-3));  /* anchors and focus land below the sticky header */
}

body {
  margin: 0;
  background: var(--color-background);
  color: var(--color-text);
  font-family: var(--font-family);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-normal);
  line-height: var(--line-height);
  -webkit-font-smoothing: antialiased;
  display: flex;  /* the footer at the bottom of the window, also when the page is shorter */
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;  /* without the browser's toolbars on phones */
}

h1,
h2,
h3 {
  margin: 0 0 var(--space-4);
  font-weight: var(--font-weight-strong);
  line-height: 1.25;
}

h1 {
  font-size: var(--font-size-title);
}

h2 {
  font-size: var(--font-size-large);
}

h3 {
  font-size: var(--font-size-base);
}

p {
  margin: 0 0 var(--space-4);
}

strong,
b {
  font-weight: var(--font-weight-strong);
}

a {
  color: var(--color-accent);
  text-decoration: underline;  /* links in text are recognizable without color (WCAG 1.4.1) */
  text-underline-offset: 0.15em;
}

/* Navigation, buttons and tables of contents are recognizable by their place and shape */
.app-name,
.app-nav a,
.gallery-nav a,
.settings-contents a,
a.button {
  text-decoration: none;
}

.app-name:hover,
.settings-contents a:hover {
  text-decoration: underline;
}

.skip-link {
  position: absolute;
  top: var(--space-2);
  left: var(--space-2);
  z-index: 40;  /* above the sticky header */
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius);
  background: var(--color-accent);
  color: var(--color-on-accent);
  transform: translateY(-200%);
}

.skip-link:focus {
  transform: none;
}

main:focus {
  outline: none;
}

:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
  border-radius: var(--radius);
}

/* Frame: header, navigation and content */

.app-header {
  position: sticky;  /* stays at the top while the page scrolls (SPEC 5.5) */
  top: 0;
  z-index: 30;
  display: flex;
  flex-wrap: wrap;  /* the search field and the user go to a second row when the links take the width */
  align-items: center;
  gap: var(--space-2) var(--space-6);
  min-height: var(--header-height);
  padding: var(--space-2) var(--space-5);
  border-bottom: var(--border);
  background: var(--color-background);
}

.app-name {
  color: var(--color-accent);
  font-weight: var(--font-weight-strong);
  font-size: var(--font-size-large);
}

.app-menu {
  display: contents;  /* its navigation and user sit in the header itself; on phones they are a menu (SPEC 5.5a) */
}

.app-header .menu-toggle,
.review-shortcut {
  display: none;  /* phones only */
}

.app-nav {
  display: flex;
  gap: var(--space-2);
}

.app-nav a {
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius);
  color: var(--color-muted);
}

.app-nav a:hover {
  background: var(--color-surface);
  color: var(--color-text);
  text-decoration: none;
}

.app-nav a[aria-current='page'] {
  background: var(--color-accent-light);
  color: var(--color-accent);
  font-weight: var(--font-weight-strong);
}

#app {
  flex: 1 0 auto;  /* takes the height the content leaves */
  width: 100%;  /* centered by its margins, which in the body's column would otherwise shrink it to its content */
  max-width: var(--content-width);
  margin: 0 auto;
  padding: var(--space-6) var(--space-5);
}

.app-footer {
  width: 100%;
  max-width: var(--content-width);
  margin: 0 auto;
  padding: var(--space-4) var(--space-5) var(--space-6);
  border-top: var(--border);
  font-size: var(--font-size-small);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  color: var(--color-muted);
}

.app-footer a {
  color: var(--color-muted);
}

/* Cards */

.card {
  padding: var(--space-5);
  border: var(--border);
  border-radius: var(--radius);
  background: var(--color-background);
}

.card + .card {
  margin-top: var(--space-4);
}

.card-surface {
  background: var(--color-surface);
}

/* Tables */

table {
  width: 100%;
  border-collapse: collapse;
}

.table-scroll {
  position: relative;  /* also clips what is positioned inside, e.g. visually hidden headers */
  overflow-x: auto;  /* a wide table scrolls in its own area, not the page (dom.ts `scrolling`) */
}

th,
td {
  padding: var(--space-2) var(--space-3);
  border-bottom: var(--border);
  text-align: left;
  vertical-align: top;
}

th {
  background: var(--color-surface);
  color: var(--color-muted);
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-strong);
}

tbody tr:hover {
  background: var(--color-accent-light);
}

/* Buttons */

button,
.button {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border: var(--border);
  border-radius: var(--radius);
  background: var(--color-background);
  color: var(--color-text);
  font: inherit;
  font-weight: var(--font-weight-strong);
  cursor: pointer;
}

button:hover,
.button:hover {
  background: var(--color-surface);
  text-decoration: none;
}

button.primary,
.button.primary {
  border-color: var(--color-accent);
  background: var(--color-accent);
  color: var(--color-on-accent);
}

button.primary:hover,
.button.primary:hover {
  background: var(--color-accent);
  filter: brightness(0.92);
}

button:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

/* Forms */

label {
  display: block;
  margin-bottom: var(--space-1);
  color: var(--color-muted);
  font-size: var(--font-size-small);
}

input,
select,
textarea {
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border: var(--border);
  border-radius: var(--radius);
  background: var(--color-background);
  color: var(--color-text);
  font: inherit;
}

input:focus,
select:focus,
textarea:focus {
  border-color: var(--color-accent);
  outline: none;
  box-shadow: var(--focus-ring);
}

input[aria-invalid='true'] {
  border-color: var(--color-warning);
}

/* Shown, not changed here (e.g. a logged-in user's name on the contact page) */
input:read-only {
  background: var(--color-surface);
  color: var(--color-muted);
}

/* Badges, values and states */

.badge {
  display: inline-block;
  padding: 0 var(--space-2);
  border-radius: var(--radius);
  background: var(--color-surface);
  color: var(--color-muted);
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-strong);
}

.badge.warning {
  background: var(--color-warning-light);
  color: var(--color-warning-text);
}

.badge.positive {
  background: var(--color-positive-light);
  color: var(--color-positive);
}

.num {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

td.num,
th.num {
  text-align: right;
}

.value-negative {
  color: var(--color-warning-text);
  font-weight: var(--font-weight-strong);
}

.value-positive {
  color: var(--color-positive);
}

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

.is-warning {
  border-left: 3px solid var(--color-warning);
  background: var(--color-warning-light);
}

/* Muted text on the warning background would fall below 4.5:1 contrast */
.is-warning .muted {
  color: var(--color-text);
}

.is-today {
  box-shadow: inset 3px 0 0 var(--color-accent);
}

.is-weekend {
  background: var(--color-surface);
}

.field {
  margin-bottom: var(--space-4);
}

.field-error {
  margin: var(--space-1) 0 0;
  color: var(--color-warning-text);
  font-size: var(--font-size-small);
}

code,
pre {
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-size: var(--font-size-small);
}

:not(pre) > code {
  overflow-wrap: anywhere;  /* long names break instead of widening the page */
  padding: 0 var(--space-1);
  border-radius: var(--radius);
  background: var(--color-surface);
}

/* Component gallery (/components) */

.gallery {
  display: grid;
  grid-template-columns: 12rem 1fr;
  gap: var(--space-6);
  align-items: start;
}

.gallery-nav {
  position: sticky;
  top: calc(var(--header-offset) + var(--space-5));
}

.gallery-nav h2 {
  color: var(--color-muted);
  font-size: var(--font-size-small);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.gallery-nav ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.gallery-nav a {
  display: block;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius);
  color: var(--color-text);
}

.gallery-nav a:hover {
  background: var(--color-surface);
  text-decoration: none;
}

.story {
  padding-bottom: var(--space-6);
  margin-bottom: var(--space-6);
  border-bottom: var(--border);
  scroll-margin-top: var(--space-5);
}

.gallery-stories {
  min-width: 0; /* let long code lines scroll instead of widening the grid column */
}

.story-example {
  padding: var(--space-5);
  border: var(--border);
  border-radius: var(--radius) var(--radius) 0 0;
}

.story-example.inline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}

.story-example > :last-child {
  margin-bottom: 0;
}

.story-code {
  margin: 0;
  padding: var(--space-4);
  overflow-x: auto;
  border: var(--border);
  border-top: 0;
  border-radius: 0 0 var(--radius) var(--radius);
  background: var(--color-surface);
  color: var(--color-text);
}

.swatches {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(14rem, 100%), 1fr));
  gap: var(--space-3);
}

.swatch {
  display: grid;
  grid-template-columns: 2.5rem 1fr;
  grid-template-rows: auto auto;
  column-gap: var(--space-3);
  align-items: center;
}

.swatch-color {
  grid-row: span 2;
  width: 2.5rem;
  height: 2.5rem;
  border: var(--border);
  border-radius: var(--radius);
}

/* Week view (/) */

.week-header {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}

.week-header h1,
.week-header p {
  margin-bottom: var(--space-1);
}

.week-nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* The date field and its "Go" as one control */
.period-go {
  display: flex;
}

.period-go input {
  border-radius: var(--radius) 0 0 var(--radius);
}

.period-go button {
  border-left: none;
  border-radius: 0 var(--radius) var(--radius) 0;
}

.week-nav [aria-disabled] {
  color: var(--color-muted);
  pointer-events: none;
}

.week-summary {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-6);
  margin-bottom: var(--space-5);
}

.week-table tr.day-details td {
  padding-top: 0;
}

.week-table tr:has(+ tr.day-details) td {
  border-bottom: 0;
}

.day-note {
  margin: 0 0 var(--space-2);
  white-space: pre-line;
}

/* The week on phones: a card per day (SPEC 5.5a) */

.day-cards {
  margin: 0;
  padding: 0;
  list-style: none;
}

.card.day-card {
  padding: var(--space-4);
}

.day-card > * + * {
  margin-top: var(--space-3);
}

.day-card-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--space-2);
}

.day-card-head > .button-small {  /* Edit */
  margin-left: auto;
}

.day-card-title h2 {
  margin: 0;
  font-size: var(--font-size-base);
}

.day-card > .day-card-line {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-4);
  margin-block: var(--space-2) 0;
}

.day-card > .entries {  /* a line between the day and its entries */
  margin-top: var(--space-3);
  padding-top: var(--space-2);
  border-top: var(--border);
}

.entries {
  margin: 0;
  padding: 0;
  list-style: none;
}

.entry {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
  padding: var(--space-1) 0;
}

.entry > .num:first-child {
  min-width: 3rem;
  text-align: right;
}

.entry-text {
  color: var(--color-muted);
}

button.button-small,
.button.button-small {
  padding: 0 var(--space-2);
  font-size: var(--font-size-small);
}

button.button-danger {
  border-color: var(--color-warning);
  color: var(--color-warning-text);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.row-actions {
  text-align: right;
}

.field-hint {
  margin: var(--space-1) 0 0;
  font-size: var(--font-size-small);
}

.form-actions {
  display: flex;
  gap: var(--space-2);
}

.day-editor {
  padding: var(--space-4);
  border: var(--border);
  border-radius: var(--radius);
  background: var(--color-surface);
}

.day-editor-fields {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: 0 var(--space-3);
}

.day-editor-fields .field-note {
  grid-column: 1 / -1;
}

.week-weekend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-4);
}

.entry-actions {
  display: flex;
  gap: var(--space-1);
  margin-left: auto;
}

/* Muted until the entry is hovered or an action has focus; muted text still has 4.5:1 contrast */
.entry-actions .button-small {
  color: var(--color-muted);
}

.entry:hover .entry-actions .button-small,
.entry-actions .button-small:focus-visible {
  color: var(--color-text);
}

.entry-editing {
  margin: var(--space-2) 0;
}

.entry-editor {
  padding: var(--space-4);
  border: var(--border);
  border-radius: var(--radius);
  background: var(--color-surface);
}

.entry-editor-fields {
  display: grid;
  grid-template-columns: 7rem 1.2fr 1fr auto;
  gap: 0 var(--space-3);
  align-items: start;
}

.entry-editor-fields [hidden] {
  display: none;
}

.entry-editor-fields .field-description {
  grid-column: 1 / -1;
}

.entry-editor-fields .field-note {
  grid-column: span 2;
}

.kind-toggle {
  display: flex;
  gap: var(--space-4);
  margin: 0 0 var(--space-3);
  padding: 0;
  border: 0;
}

.kind-option,
.coding-option {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  color: var(--color-text);
  font-size: var(--font-size-base);
}

.kind-option input,
.coding-option input {
  width: auto;
}

.coding-option {
  margin-top: 1.6rem;
}

.history {
  margin: var(--space-1) 0 var(--space-2) 3.5rem;
  padding: var(--space-2) var(--space-3);
  border-left: 2px solid var(--color-border);
  font-size: var(--font-size-small);
}

.history-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.history-list li + li {
  margin-top: var(--space-1);
}

/* The whole of an entry in a dialog (entry-details.ts) */

.entry-details + .entry-details {
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: var(--border);
}

.entry-details h3 {
  margin-bottom: var(--space-2);
  font-size: var(--font-size-base);
}

.details-list {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--space-1) var(--space-3);
  margin: 0 0 var(--space-3);
}

.details-list dt {
  color: var(--color-muted);
}

.details-list dd {
  margin: 0;
  overflow-wrap: anywhere;
}

.entry-details .history {
  margin: var(--space-1) 0 var(--space-3);
}

/* Review page (/review) */

.review-header {
  margin-bottom: var(--space-5);
}

.review-status {
  font-weight: var(--font-weight-strong);
}

.review-section {
  margin-bottom: var(--space-6);
}

.review-section h2 .badge {
  vertical-align: middle;
}

.review-toolbar {
  display: grid;
  grid-template-columns: 1fr 1fr auto;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}

.review-table td {
  vertical-align: middle;
}

.review-table .row-actions {
  white-space: nowrap;
}

.review-table .row-actions > * + * {
  margin-left: var(--space-1);
}

.clock-button {
  margin-left: var(--space-2);
}

.select-cell {
  width: 2.5rem;
}

.select-cell input {
  width: auto;
}

.rename-form {
  display: inline-flex;
  gap: var(--space-1);
}

.rename-input {
  width: 9rem;
  padding: 0 var(--space-2);
}

.split-input {
  width: 16rem;
  padding: 0 var(--space-2);
}

/* Month report (/month) */

.work-report {
  margin-top: var(--space-5);
}

.work-service {
  margin-bottom: var(--space-5);
}

.work-service-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  padding-bottom: var(--space-2);
  border-bottom: 2px solid var(--color-border);
}

.work-service-header h2,
.work-service-header h3 {
  margin: 0;
}

.work-ticket {
  width: 9rem;
  white-space: nowrap;
}

.work-descriptions {
  margin: 0;
  padding-left: var(--space-4);
}

/* Year report (/year) */

.year-cards,
.search-cards,
.report-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}

.report-cards {
  grid-template-columns: repeat(auto-fill, minmax(min(16rem, 100%), 1fr));
}

.year-cards .card + .card,
.search-cards .card + .card,
.report-cards .card + .card {
  margin-top: 0;
}

/* The period buttons, then a little apart the exports of that period */
.report-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
}

.report-exports {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.report-cards h3 {
  margin: 0 0 var(--space-2);
}

.report-cards .tile-value {
  margin: 0;
}

.report-member {
  display: block;
  color: var(--color-text);
  text-decoration: none;
}

.report-member:hover {
  background: var(--color-surface);
}

.report-open {
  display: block;
  margin-top: var(--space-3);
  color: var(--color-accent);
  font-size: var(--font-size-small);
}

.report-hours {
  margin: var(--space-3) 0 0;
  padding: 0;
  list-style: none;
}

.report-hours li {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-1) 0;
  border-top: var(--border);
}

.work-service-header + .report-hours {
  margin-top: 0;
}

.work-service-header + .report-hours li:first-child {
  border-top: 0;
}

.card-table td {
  padding: var(--space-1) 0;
  border-bottom: 0;
}

.card-table td.card-table-list {  /* a list of figures, e.g. the top activity types: wraps on narrow screens */
  padding-left: var(--space-4);
  white-space: normal;
}

.card-table tr:hover {
  background: none;
}

.card-table-total td {
  border-top: var(--border);
}

.year-months tr.is-future td {
  color: var(--color-muted);
}

.year-work {
  margin-top: var(--space-6);
}

/* Search page (/search) */

.search-form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr));
  align-items: end;
  gap: 0 var(--space-4);
  margin-bottom: var(--space-5);
}

.search-form .field-text {
  grid-column: 1 / -1;  /* a row of its own */
}

.search-actions {
  margin-bottom: var(--space-4);
}

.search-cards h2 {
  margin-top: 0;
}

.search-more {
  margin-top: var(--space-3);
}

/* Editable tables (settings page) */

.list-form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.list-form input {
  flex: 1 1 10rem;
  width: auto;
}

/* A labelled control of the form for a new record */
.list-field {
  display: flex;
  flex: 1 1 10rem;
  flex-direction: column;
  gap: var(--space-1);
}

.list-form .list-field > input,
.list-form .list-field > select {
  flex: none;  /* not the row's flex basis, which would make them tall in this column */
  width: 100%;
}

.list-field:has(.weekday-picker) {
  flex: 2 1 20rem;
}

.list-form:has(.list-field) {
  align-items: flex-end;
}

.list-table + .list-form,
.table-scroll + .list-form {
  margin-top: var(--space-3);
}

.list-table .list-form input {
  padding: 0 var(--space-2);
}

/* Settings (/settings) */

.balance-form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(14rem, 100%), 1fr));
  column-gap: var(--space-4);
  max-width: 40rem;
}

.balance-form .form-error,
.balance-form .form-actions {
  grid-column: 1 / -1;
}

.list-table .list-form strong {
  align-self: center;
  min-width: 3rem;
}

.settings-contents {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}

.weekday-picker {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  padding: 0 var(--space-2);
  border: var(--border);
  border-radius: var(--radius);
}

.weekday-picker label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--font-size-small);
}

.weekday-picker input {
  width: auto;
}

.checkbox-field {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--font-size-small);
  white-space: nowrap;
}

.checkbox-field input {
  width: auto;
}

.checkbox-field[hidden] {
  display: none;
}

.list-form select {
  flex: 1 1 10rem;
  width: auto;
}

/* Booking days off (week page) */

.days-off-form {
  margin-bottom: var(--space-5);
}

.days-off-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(10rem, 100%), 1fr));
  column-gap: var(--space-4);
}

.days-off-preview {
  margin: 0 0 var(--space-3);
}

.dialog {
  max-width: 34rem;
  padding: var(--space-5);
  border: var(--border);
  border-radius: var(--radius);
  color: var(--color-text);
}

.dialog::backdrop {
  background: rgb(54 69 79 / 30%);
}

.dialog h2 {
  margin-top: 0;
}

.story-dialog {
  position: static;  /* shown in place on the components page; ask() opens it modally */
  margin: 0;
}

/* Initial setup (/setup) */

.setup-steps {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin: 0 0 var(--space-4);
  padding: 0;
  list-style: none;
  color: var(--color-muted);
  font-size: var(--font-size-small);
  counter-reset: step;
}

.setup-steps li::before {
  content: counter(step) '. ';
  counter-increment: step;
}

.setup-steps .is-current {
  color: var(--color-accent);
  font-weight: var(--font-weight-strong);
}

.setup-steps .is-done {
  color: var(--color-text);
}

.setup-step {
  max-width: 48rem;
}

.setup-step h2 {
  margin-top: 0;
}

.setup-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(14rem, 100%), 1fr));
  column-gap: var(--space-4);
}

.setup-note {
  margin-bottom: var(--space-4);
  font-size: var(--font-size-small);
}

.setup-step .list-form {
  margin-bottom: var(--space-2);
}

.setup-add {
  margin-bottom: var(--space-4);
}

.setup-summary {
  margin-bottom: var(--space-4);
}

.setup-summary th {
  padding: var(--space-1) var(--space-4) var(--space-1) 0;
  background: none;
  color: var(--color-muted);
  font-weight: normal;
  text-align: left;
}

.field-label {
  display: block;
  margin-bottom: var(--space-1);
  font-size: var(--font-size-small);
}

.theme-preview {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin: 0 0 var(--space-4);
  padding: var(--space-2) var(--space-3);
  border: var(--border);
  border-radius: var(--radius);
}

.theme-preview legend {
  padding: 0 var(--space-1);
  font-size: var(--font-size-small);
}

.theme-preview label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

.theme-preview input {
  width: auto;
}

.work-modes {
  display: grid;
  gap: var(--space-2);
  margin: 0 0 var(--space-4);
  padding: var(--space-2) var(--space-3);
  border: var(--border);
  border-radius: var(--radius);
}

.work-modes legend {
  padding: 0 var(--space-1);
  font-size: var(--font-size-small);
}

.work-modes label {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
}

.work-modes input {
  width: auto;
}

/* Dashboard (/) */

.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(14rem, 100%), 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}

.tile {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-4) var(--space-5);
  border: var(--border);
  border-radius: var(--radius);
  color: var(--color-text);
  text-decoration: none;
}

.tile:hover {
  background: var(--color-surface);
}

.tile-label,
.tile-detail {
  color: var(--color-muted);
  font-size: var(--font-size-small);
}

.tile-value {
  font-size: var(--font-size-title);
  font-weight: var(--font-weight-strong);
}

.dashboard-section {
  margin-bottom: var(--space-6);
}

.dashboard-section-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}

.dashboard-section-header h2 {
  margin: 0;
}

.segmented {
  position: relative;  /* the radio buttons inside are positioned */
  display: inline-flex;
  flex-wrap: wrap;
  border: var(--border);
  border-radius: var(--radius);
}

.segmented label {
  padding: var(--space-1) var(--space-3);
  font-size: var(--font-size-small);
  cursor: pointer;
}

.segmented label + label {
  border-left: var(--border);
}

.segmented input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  opacity: 0;
}

.segmented label:has(input:checked) {
  background: var(--color-accent-light);
  color: var(--color-accent);
  font-weight: var(--font-weight-strong);
}

.segmented label:has(input:focus-visible) {
  box-shadow: var(--focus-ring);
}

.dashboard-columns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
  gap: var(--space-4);
}

.dashboard-columns .card + .card {
  margin-top: 0;
}

.dashboard-columns h2 {
  margin-top: 0;
}

.coming-up {
  margin: 0;
  padding-left: var(--space-4);
}

/* Balance chart: plain SVG in the color variables, so both themes apply */

.chart {
  position: relative;
}

.chart-plot {
  display: block;
  max-width: 100%;
}

.chart-text {
  fill: var(--color-muted);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

.chart-end-label {
  fill: var(--color-text);
  font-weight: var(--font-weight-strong);
}

.chart-grid {
  stroke: var(--color-border);
  stroke-width: 1;
}

.chart-zero {
  stroke: var(--color-muted);
  stroke-width: 1;
}

.chart-line {
  fill: none;
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.chart-area {
  opacity: 0.1;
}

.chart-above .chart-line {
  stroke: var(--color-accent);
}

.chart-above .chart-area,
.chart-above.chart-dot,
.chart-above .chart-dot {
  fill: var(--color-accent);
}

.chart-below .chart-line {
  stroke: var(--color-warning);
}

.chart-below .chart-area,
.chart-below.chart-dot,
.chart-below .chart-dot {
  fill: var(--color-warning);
}

.chart-dot {
  stroke: var(--color-background);
  stroke-width: 2;
}

.chart-crosshair {
  stroke: var(--color-muted);
  stroke-width: 1;
}

.chart-tooltip {
  position: absolute;
  top: 0;
  display: flex;
  flex-direction: column;
  padding: var(--space-1) var(--space-2);
  border: var(--border);
  border-radius: var(--radius);
  background: var(--color-background);
  font-size: var(--font-size-small);
  pointer-events: none;
}

.chart-tooltip[hidden] {
  display: none;
}

.chart-table {
  margin-top: var(--space-3);
  font-size: var(--font-size-small);
}

.chart-table summary {
  color: var(--color-accent);
  cursor: pointer;
}

/* Login (/login) and the user in the header */

.app-user {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-left: auto;
}

/* Plain icons that act, not framed as buttons: the dark mode switch and the menu (☰, SPEC 5.5) */
.icon-button {
  justify-content: center;
  min-width: 24px;  /* WCAG 2.5.8 target size */
  min-height: 24px;
  padding: var(--space-1);
  border: 0;
  background: none;
  color: var(--color-muted);
}

.icon-button:hover {
  background: none;
  color: var(--color-text);
}

.icon-button svg {
  display: block;
}

/* The menu (☰): a panel below it with Team, Settings, Admin and "Log out" */
.account-menu {
  position: relative;
}

.account-toggle {
  gap: var(--space-1);  /* before the badge of open invitations */
}

.account-links {
  position: absolute;
  top: calc(100% + var(--space-2));
  right: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  min-width: 12rem;
  padding: var(--space-2);
  border: var(--border);
  border-radius: var(--radius);
  background: var(--color-background);
  box-shadow: 0 4px 12px rgb(0 0 0 / 0.12);  /* lifted above the page it covers */
}

.account-toggle[aria-expanded='false'] + .account-links {
  display: none;
}

.account-links > a,
.account-links > .logout {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: 0;
  border-radius: var(--radius);
  background: none;
  color: var(--color-text);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-normal);
  text-decoration: none;
}

.account-links > a:hover,
.account-links > .logout:hover {
  background: var(--color-surface);
}

.account-links > a[aria-current='page'] {
  background: var(--color-accent-light);
  color: var(--color-accent);
  font-weight: var(--font-weight-strong);
}

.account-links > .logout {
  margin-top: var(--space-1);
  border-top: var(--border);
  border-radius: 0 0 var(--radius) var(--radius);
}

body:has(main[data-page='login']) :is(.app-nav, .nav-search),
body:has(main[data-page='register']) :is(.app-nav, .nav-search),
body:has(main[data-page='setup']) :is(.app-nav, .nav-search),
body:has(main[data-page='password']) :is(.app-nav, .nav-search),
body:has(main[data-page='two-factor']) :is(.app-nav, .nav-search),
body:has(main[data-page='imprint']) :is(.app-nav, .nav-search),
body:has(main[data-page='privacy']) :is(.app-nav, .nav-search),
body:has(main[data-page='contact']) :is(.app-nav, .nav-search),
body:has(main[data-page='search']) .nav-search {  /* the search page has its own form */
  display: none;
}

.nav-search input {
  width: 14rem;
  padding: var(--space-1) var(--space-3);
}

.one-time-password {
  font-family: ui-monospace, monospace;  /* every character easy to tell apart */
  font-size: var(--font-size-large);
  letter-spacing: 0.05em;
  user-select: all;  /* one click selects it for copying */
}

.login,
.imprint {
  max-width: 28rem;
  margin: var(--space-6) auto;
}

.contact {
  max-width: 36rem;
  margin: var(--space-6) auto;
}

.privacy {
  max-width: 42rem;
  margin: var(--space-6) auto;
  overflow-wrap: anywhere;
}

.privacy h2 {
  margin-top: var(--space-5);
  font-size: var(--font-size-large);
}

.contact-trap {  /* the field for bots (SPEC 5.14): off screen, not merely hidden, which some bots skip */
  position: absolute;
  left: -10000px;
}

.login-form .field {
  margin-bottom: var(--space-4);
}

.login-hint {
  margin: var(--space-4) 0 0;
  font-size: var(--font-size-small);
}

.account-heading {
  margin: var(--space-6) 0 var(--space-3);
}

.two-factor-qr {
  display: block;
  margin: var(--space-2) 0;
  background: #fff;  /* a QR code needs a light background in the dark theme too */
  border-radius: var(--radius);
}

.recovery-code-list {
  columns: 2;
  margin: var(--space-3) 0;
  padding-left: var(--space-5);
  font-size: var(--font-size-large);
}

.root-reset {
  margin-top: var(--space-6);
}

.root-reset summary {
  cursor: pointer;
  margin-bottom: var(--space-3);
}

/* Team invitations in the settings */

.invitation-list {
  display: grid;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.invitation-list button {
  margin-left: var(--space-2);
}

.admin-users select {
  width: auto;
}

.admin-badge {
  margin-left: var(--space-2);
}

.invite-form {
  margin-top: var(--space-4);
}

/* Team view: the member chooser on the dashboard and the read-only banner */

.member-chooser {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.member-chooser select {
  width: auto;
}

.team-view-banner {
  margin-bottom: var(--space-4);
}

/* Narrow screens and zoom (WCAG 1.4.10 Reflow: 320 CSS px, i.e. 1280 px at 400 %): no page-wide horizontal scrolling */

@media (max-width: 40rem) {
  .app-header {
    flex-wrap: wrap;
    height: auto;
    min-height: var(--header-height);
    max-height: 100dvh;  /* the opened menu scrolls within the screen */
    overflow-y: auto;
    padding: var(--space-2) var(--space-4);
    gap: var(--space-2) var(--space-4);
  }

  /* One row with the name, the review count and "Menu"; the menu opens below it (SPEC 5.5a) */
  .app-name {
    margin-right: auto;
  }

  .app-header .menu-toggle,
  .review-shortcut:not([hidden]) {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
  }

  .review-shortcut {
    color: var(--color-muted);
    text-decoration: none;  /* like the links of the navigation */
  }

  .app-menu {
    display: none;
    flex-direction: column;
    gap: var(--space-3);
    width: 100%;
    padding-bottom: var(--space-2);
  }

  .menu-toggle[aria-expanded='true'] + .app-menu {
    display: flex;
  }

  .app-nav {
    flex-direction: column;
    gap: var(--space-1);
  }

  .app-user {
    flex-wrap: wrap;
    width: 100%;
    margin-left: 0;
  }

  /* The entries of ☰ listed directly in the phone's menu, below name and dark mode switch */
  .account-menu {
    width: 100%;
  }

  .account-toggle {
    display: none;
  }

  .account-links,
  .account-toggle[aria-expanded='false'] + .account-links {
    position: static;
    display: flex;
    min-width: 0;
    padding: 0;
    border: 0;
    box-shadow: none;
  }

  /* Pages without navigation show what they show on the desktop, without a menu */
  body:has(main:is([data-page='login'], [data-page='register'], [data-page='setup'], [data-page='password'],
                   [data-page='two-factor'], [data-page='imprint'], [data-page='privacy'],
                   [data-page='contact'])) .app-header .menu-toggle {
    display: none;
  }

  body:has(main:is([data-page='login'], [data-page='register'], [data-page='setup'], [data-page='password'],
                   [data-page='two-factor'], [data-page='imprint'], [data-page='privacy'],
                   [data-page='contact'])) .app-menu {
    display: contents;
  }

  .nav-search,
  .nav-search input {
    width: 100%;
  }

  #app {
    padding: var(--space-5) var(--space-4);
  }

  .gallery {
    grid-template-columns: minmax(0, 1fr);  /* the navigation above the components */
  }

  /* Entries and forms in the week table stay at the left of its scroll area, as wide as the screen */
  .week-table .day-details > td > *,
  .week-table .day-editor-row > td > * {
    position: sticky;
    left: 0;
    max-width: calc(100vw - 2 * var(--space-4) - 2 * var(--space-3));
  }

  .day-editor-fields,
  .entry-editor-fields {
    grid-template-columns: minmax(0, 1fr);
  }

  .entry-editor-fields .field-note {
    grid-column: 1 / -1;
  }

  /* Fields with 16 px text: phones zoom in on a smaller one when it gets focus (SPEC 5.5a) */
  input,
  select,
  textarea {
    font-size: 1rem;
  }

  /* List tables (`stacks`, SPEC 5.5a): each row a block, its first cell the title on a line of its own, the others as
     "label value" (the column's header, `data-label`) side by side, the actions at the right */
  table.stacks,
  .stacks > tbody {
    display: block;
  }

  .stacks > thead {
    position: absolute;  /* for screen readers only, like .visually-hidden */
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
  }

  .stacks > thead:has(input) {  /* except "select all": the checkbox stays, as "All" */
    position: static;
    display: block;
    width: auto;
    height: auto;
    clip: auto;
  }

  .stacks > thead:has(input) th:not(.select-cell) {
    display: none;
  }

  .stacks > thead .select-cell {
    display: flex;
    gap: var(--space-2);
    padding: var(--space-2) 0;
    border: 0;
    background: none;
  }

  .stacks > thead .select-cell::after {
    content: 'All';
  }

  .stacks tr {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-1) var(--space-4);
    padding: var(--space-3) 0;
    border-bottom: var(--border);
  }

  .stacks tr[hidden] {  /* e.g. filtered out in the review */
    display: none;
  }

  .stacks > tbody .select-cell {
    align-self: center;
    width: auto;
  }

  .review-toolbar {
    grid-template-columns: minmax(0, 1fr) auto;
  }

  .review-toolbar > :first-child {  /* the filter on a line of its own */
    grid-column: 1 / -1;
  }

  .stacks > tbody :is(td, th) {
    padding: 0;
    border: 0;
    text-align: left;
  }

  .stacks td[data-label]::before {
    content: attr(data-label) ' ';
    color: var(--color-muted);
  }

  .stacks :is(td, th):not(.select-cell):first-child,
  .stacks .select-cell + :is(td, th) {
    flex: 1 0 70%;  /* the title takes the line, beside a selection checkbox */
    font-weight: var(--font-weight-strong);
  }

  .stacks :is(td, th):not(.select-cell):first-child::before,
  .stacks .select-cell + :is(td, th)::before {
    content: none;
  }

  .stacks .row-actions {
    margin-left: auto;
  }

  /* The month report: a ticket and its hours on one line, its descriptions below */
  .stacks.work-tickets tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
  }

  .stacks.work-tickets td:nth-child(2) {
    grid-row: 2;
    grid-column: 1 / -1;
    font-weight: var(--font-weight-normal);
  }
}

/* Touch screens (SPEC 5.5a): buttons and links that act at least 44 px, an easy target for a finger; after the rules
   above, so it also overrides the 24 px of the dark mode switch */

@media (pointer: coarse) {
  button,
  .button,
  .icon-button,
  .app-nav a,
  .account-links > a,
  .review-shortcut,
  .segmented label {
    min-width: 44px;
    min-height: 44px;
  }

  .app-nav a,
  .segmented label {
    display: flex;
    align-items: center;
    gap: var(--space-1);  /* e.g. before the review count, as flex drops the space */
  }

  summary {  /* a list item, which keeps its disclosure triangle */
    line-height: 44px;
  }
}

/* Printed (the team report's "Save as PDF"): the content only, without navigation and buttons, and no card split
   across two pages; last, so it overrides the rules above */

@media print {
  .app-header,
  .app-footer,
  .skip-link,
  .week-nav,
  .member-chooser,
  .report-exports,
  .report-open {
    display: none;
  }

  .card {
    break-inside: avoid;
  }
}

/* Support page (/support) */

.support-search {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  max-width: 36rem;
  margin-bottom: var(--space-5);
}

.support-search input {
  flex: 1 1 14rem;
  width: auto;
}

.support-message {
  max-width: 48rem;
}

.message-text {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.support-message .field,
.support-note {
  max-width: 36rem;
  margin-top: var(--space-4);
}
