/* =====================================================================
   COMPANY COLOUR (house style)
   ---------------------------------------------------------------------
   One colour drives the whole app: --brand. Buttons, links, switches, focus
   rings, the small avatars and the .pdf export button all derive from it with
   color-mix(), in both themes — every such line below is marked  BRAND .

   For a rebrand (say the company turns orange), change --brand and nothing
   else. Or change it without touching code: App-beheer → Huisstijl in the app
   (needs the manage_app permission). That is saved in Supabase (app_settings)
   and set on <html> by admin.js, which wins over the value here — this line is
   only the default, and what "Standaard" in App-beheer goes back to.

   After a change of colour, look over the lines marked BRAND by eye: a very
   light brand colour would need darker text on the buttons (--color-on-button-
   primary). Colours NOT marked BRAND are neutral greys or status colours
   (green = ok, red = error / denied, orange = waiting) and stay as they are.
   The company logo is a picture (image/logo.jpg, top right of the
   banner) and is swapped separately.
   ===================================================================== */
:root {
	--brand: #25596f;                 /* BRAND: the default blue-green (Sep 25; was #1a5381) */
}

/* ---------- Theme colors ---------- */
/* All colors live here, named by what they are used for (not by what they look like).
   The light theme is the default. The dark theme overrides the same names below.
   To change a color, change it here: every element using that name follows.
   To add a color, add it to BOTH blocks. */
:root {
	color-scheme: light;

	/* Page */
	--color-page: #dcdfe4;            /* gray background / content area */
	/* Wallpaper behind the whole app. It is a light image, so the dark theme turns it
	   down to a faint texture (a veil of the page colour) instead of full strength. */
	--page-image: url("image/wallpaper1.jpg");
	--page-image-veil: transparent;   /* how much of the page colour lies over the picture */
	--color-panel: #ffffff;           /* white top panel */
	--color-text: #1c1c1e;            /* text in the content area */
	--color-accent: var(--brand);     /* BRAND: switches, focus rings */

	/* Banner: graphite, a touch lighter than the nav's near-black (Sep 25). Both can be set
	   in App-beheer; that colour then goes on <html> and wins in both themes. */
	--color-banner: #26282c;
	--color-banner-strong: var(--color-banner); /* notch strip, avatar letters */
	--color-banner-shadow: #0000001a;
	--color-on-banner: #ffffff;       /* avatar background */
	--color-on-banner-soft: #e0e3e7;
	--color-banner-text: var(--color-nav-item-icon); /* grey text on the banner (not used at the moment) */
	--color-banner-name: #ffffff;     /* user name */
	--color-banner-soft: #c8d5db;     /* the date under the name */
	--color-banner-menu-icon: #ffffff; /* the menu (settings) icon under the photo (Sep 28, was the date's colour) */
	--color-banner-hover: #ffffff1f;  /* behind the menu icon under the mouse */

	/* Navigation */
	/* A near-black pill floating on the wallpaper, icons only, the current page a white
	   pill inside it (Sep 25, replacing the grey bar in a white panel) */
	--color-nav: #141416;             /* nav bar, tab and round expand button */
	--color-nav-border: #ffffff00;    /* edge of the bar: none needed on a light page */
	--color-nav-shadow: #0000002e;
	--color-nav-item: #ffffff00;      /* page buttons sit straight on the bar */
	--color-nav-item-hover: #ffffff1a;
	--color-nav-item-press: #ffffff2e; /* unpin button under the mouse */
	--color-nav-divider: #ffffff12;   /* line above the unpin button (pinned nav) */
	--color-nav-active-pinned: #ebebee; /* current page in the pinned nav: a touch softer than white */
	--color-nav-item-text: #e5e5ea;   /* labels in the open list */
	--color-nav-item-icon: #a3a3ab;
	--color-nav-active: #ffffff;      /* current page */
	--color-nav-active-text: #141416;
	--color-nav-active-shadow: #00000000;
	--color-nav-tab-arrow: #c7c7cc;
	--color-nav-dim: #00000014;       /* page behind the open nav: just dark enough to see where the blur starts */
	--blur-darken: 5%;                /* how much a blurred bar darkens what is behind it */

	/* Settings pop-up (iOS style) */
	--color-sheet: #f5f5f9;           /* pop-up background (Oct 20: one light grey for the app, was #f2f2f6) */
	--color-sheet-backdrop: #0000004d;
	--color-group: #ffffff;           /* white groups */
	--color-group-hover: #f7f7f9;
	--color-separator: #e7e7e8;
	--color-label: #000000;
	--color-label-secondary: #85858a; /* section headers, unselected options */
	--color-fill: #eeeeef;            /* selected option */
	--color-week-pill: color-mix(in oklab, var(--color-button-primary) 45%, #8b9098);   /* the week pill: the
	                                     main colour most of the way to grey (Sep 29) */
	--color-on-week-pill: #ffffff;
	--color-hours-field: #f5f5f9;     /* hour and parking fields on an uurbon (Oct 20: the app's light grey) */
	--color-uurbon-value: #3a3a3c;    /* typed values in the top groups of an uurbon */
	--color-close: #d9d9e0;           /* round close button in pop-ups */
	--color-close-hover: #c7c7d0;
	--color-close-icon: #3a3a3c;      /* the × itself */
	--color-switch-off: #c5c5c7;
	--color-switch-knob: #ffffff;
	--color-switch-company: #485d70;   /* a switch that is on without the main colour, a colour of its own (company cards, Sep 30) */
	--color-destructive: #be5853;     /* log out */
	--color-delete-soft: #dfe1e6;     /* round bin in a pop-up's header: grey… (Sep 28, was light red) */
	--color-delete-soft-hover: #cdd1d8;
	--color-delete-soft-icon: #4a4a4f; /* …with a dark grey bin */

	/* Pages and cards */
	--color-card: #f5f5f9;            /* cards inside a panel (Oct 20: the app's light grey, was #f2f2f6) */
	--color-card-hover: #eaeaef;      /* a vehicle / person card under the mouse */
	--color-panel-title: #2c2c2e;     /* big title at the top of a panel */
	--color-card-shadow: #00000000;
	--color-text-secondary: #6e6e73;
	--color-placeholder: #a1a1a6;
	--color-link: var(--brand);                                      /* BRAND */
	--color-error: #d70015;
	--color-success: #1d7a36;
	--color-filter-track: #f5f5f9;    /* segmented filter, search bar, sort pill above lists: the cards' grey (Oct 20) */
	--color-filter-active: #ffffff;
	--color-filter-shadow: #0000001f;
	--color-menu: #ffffff;            /* dropdown menus */
	--color-menu-hover: #f0f0f4;
	--color-menu-shadow: #00000029;
	--color-sort-direction: #ffffff;  /* round reverse-order button */
	--color-sort-direction-hover: #f4f4f7;
	--color-tile: #f5f5f9;            /* small panels inside a page (Oct 20: the app's light grey) */
	--color-tile-separator: #e2e2e7;
	--color-tile-item: #ffffff;       /* rows inside a tile (people) */
	--color-tile-item-hover: #fafafc;
	--color-field: #ffffff;           /* text inputs */
	--color-field-border: #ececf0;    /* barely darker than the field */
	--color-field-focus: color-mix(in srgb, var(--brand) 18%, transparent); /* BRAND: soft ring around the focused input */
	--color-avatar: color-mix(in srgb, var(--brand) 14%, #ffffff);   /* BRAND: small people avatars */
	--color-avatar-text: color-mix(in srgb, var(--brand) 85%, #000000); /* BRAND */
	--color-photo-backdrop: #000000b3;/* behind a photo shown full size */
	--color-photo-shadow: #00000059;
	/* Vehicle calendar. Icy blue-grey on purpose: anything with green in it reads as
	   a colour of its own next to the blue of the app. */
	/* Calendars (vehicles, new assignment, date picker): white blocks with only today and
	   the taken / chosen days filled, in the company colour (Sep 25) */
	--color-agenda: #ffffff;          /* the two flat blocks the calendar sits in */
	--color-day-today: var(--brand);  /* BRAND: today, the strongest fill */
	--color-on-day-today: #ffffff;
	--color-day-booked: color-mix(in srgb, var(--brand) 22%, #ffffff);  /* BRAND: a day that is taken / chosen */
	--color-on-day-booked: color-mix(in srgb, var(--brand) 85%, #000000); /* BRAND */
	--color-day-past: color-mix(in srgb, var(--brand) 6%, #e1e2e5);     /* a taken day gone by: nearly grey */
	--color-on-day-past: color-mix(in srgb, var(--brand) 12%, #6f7278);
	--color-day-weekend: #a7acb6;     /* the date number on a Saturday or Sunday */
	--color-expired: #d0574f;         /* an inspection date that has run out */
	--color-soon: #d98b12;            /* an inspection date that is nearly there */
	--color-vehicle-photo: #e4e7ee;   /* box behind a vehicle photo (or its icon) */
	--color-vehicle-photo-icon: #7b8393;
	--color-size: #d7dbe1;            /* size buttons that are not picked */
	--color-size-hover: #c8cdd6;
	--color-size-text: #6e6e73;
	--color-badge-remove: #dfe1e6;        /* bin badge on a profile photo */
	--color-badge-remove-hover: #cdd1d8;
	--color-on-badge-remove: #4a4a4f;
	--color-user-check-ok: #2f9e55;             /* Users list: filled in and valid (vibrant again, Sep 28) */
	--color-user-check-warn: #8e8e93;           /* …runs out soon (the grey !) */
	--color-user-check-bad: #d0342c;            /* …missing or run out */
	--color-user-check-extra: #b4b4b9;          /* …certificates nobody asked for: the grey ✓ and ~ (Sep 30) */
	--color-cert-required: #fde4e2;             /* "Vereist" chip on a certificate (Sep 28) */
	--color-on-cert-required: #b3261e;
	--color-cert-recommended: #e2edfb;          /* "Gewenst" chip */
	--color-on-cert-recommended: #1f5fae;
	--color-cert-info: #4f7fbf;                 /* a lapsed certificate that isn't required: information */
	--color-info: #4f7fbf;                      /* the round button of an info tip (Oct 20), the same blue as above */
	--color-you: #96c7a4;                       /* the round "this is you" mark after your own name: a soft green close to the rows' grey (Oct 20) */
	--color-on-you: #f3fbf5;                    /* the star in it, lighter still */
	--color-user-row: #f5f5f9;                  /* a person's row in the Gebruikers list (Oct 20: the same light grey as the cards) */
	--color-on-info: #ffffff;                   /* the "i" on it */
	--color-info-tip: #eff4fb;                  /* the bubble its text opens in: another, lighter soft blue */
	--color-on-info-tip: #34598c;               /* the text in that bubble */
	--color-cert-pending: #fbecd3;              /* "Wacht op controle" chip (Sep 28, migration 026) */
	--color-on-cert-pending: #8a5300;
	--color-req-track: #e6e6eb;                 /* Nee / Gewenst / Vereist in the Functies pop-up */
	--color-req-active: #ffffff;
	--color-user-summary: #8e8e93;              /* "Geen problemen" / "1 aandachtspunt" on a card */
	--color-user-row-top: #000000;              /* a user row's top line: name, column names */
	--color-user-row-bottom: #222222;           /* …its bottom line: functie, values */
	--color-user-head: #e6edf8;                 /* the fills of the Gebruikers header row (Oct 21): a soft blue, apart from the grey rows */
	--color-user-head-active: #c4d3e9;          /* …the fill of the column the list is ordered by: a step deeper */
	--color-on-user-head: #557cb6;              /* …the column names on them: a lighter blue */
	--color-on-user-head-active: #22416d;       /* …the column the list is ordered by, and one under the mouse */
	--color-user-pinned: #d0342c;               /* the ring around a pinned person's photo (Oct 21) */
	--color-user-col-separator: var(--color-panel);   /* the stripes between a row's columns (Oct 21): the page's own colour, so dark follows by itself */
	--color-scroll-track: #f2f2f6;              /* the one visible scrollbar, under the Gebruikers list (Oct 21): its track */
	--color-scroll-thumb: #dcdce2;              /* …and the part you drag, a little darker */
	--color-pin-resizer: #c4c4cb;               /* the grip between the pinned nav and the page, on hover (Oct 21) */
	--color-company-photo-button: #dfe1e6;      /* camera button beside a company's picture (Sep 28) */
	--color-company-photo-button-hover: #cdd1d8;
	--color-on-company-photo-button: #4a4a4f;
	--color-button-destructive: #d92b20;  /* deny a request, delete for good */
	--color-button-destructive-hover: #b3241b;
	--color-on-button-destructive: #ffffff;
	--color-button-primary: var(--brand);                            /* BRAND */
	--color-button-primary-hover: color-mix(in srgb, var(--brand) 78%, #000000); /* BRAND */
	--color-on-button-primary: #ffffff;
	--color-button-secondary: #e3e3e8;
	--color-button-secondary-hover: #d8d8de;
	--color-project-add: var(--brand);    /* BRAND: the round + for a project on the new uurbon (Sep 28) */
	--color-on-project-add: #ffffff;
	--color-project-badge: #e6ebef;       /* the square in front of a project on Projecten */
	--color-on-project-badge: #3b5566;
	--color-button-pdf: #d9d9e0;          /* the .pdf export button: grey like the close × (Sep 28) */
	--color-button-pdf-hover: #c7c7d0;
	--color-on-button-pdf: #3a3a3c;
	--color-panel-button: #f5f5f9;    /* round buttons in a panel header: fullscreen, ⋯ (Oct 20, was #efeff3) */
	--color-panel-button-hover: #e4e4e9;
	--color-panel-button-icon: #3a3a3c;
	--color-on-button-secondary: #1c1c1e;
	--color-toast: #1c1c1e;
	--color-on-toast: #ffffff;
	--color-toast-shadow: #00000033;

	/* The coloured bar down the left edge of a card. Saturated on purpose: at four
	   pixels wide a chip colour would read as nothing at all. */
	--color-mark-draft: #b8c1d6;
	--color-mark-waiting: #a1bae7;
	--color-mark-ok: #a0ddb0;
	--color-mark-denied: #db7f78;
	--color-mark-project: #D0D5DC;   /* a project whose company has no colour (Sep 30) */

	/* Status chips */
	/* A draft is nobody's business yet: neutral, but still a shade off the card it
	   sits on, in both themes (--color-status-completed is the card's own colour in
	   the dark theme, so the chip disappeared into it). */
	--color-status-draft: #c0c5d1;
	--color-on-status-draft: #4c515c;

	/* The P badge on a card: its own pair, so it does not follow a status colour */
	--color-parking: #e0e3ea;
	--color-on-parking: #4c515c;
	--color-status-request: #fff0d6;
	--color-on-status-request: #8a4b00;
	--color-status-submitted: #dfe6ee;   /* Ingediend: a blue-grey, no longer the yellow (Sep 25) */
	--color-on-status-submitted: #3f5569;
	--color-status-accepted: #a0ddb0;
	--color-on-status-accepted: #3f8151;
	--color-status-in-progress: #ddf2e3;
	--color-on-status-in-progress: #1d6b33;
	--color-status-completed: #ebebef;
	--color-on-status-completed: #58585d;
	--color-status-denied: #e4908a;
	--color-on-status-denied: #722420;

	/* No connection: the sign that covers the app */
	--color-attention: #f6d3cf;       /* the red ! and the "Let op" chip: something expires */
	--color-on-attention: #8e1b12;

	/* Messages on the Hub: the sender picks blue or red */
	--color-message-blue: #dbe8f6;
	--color-on-message-blue: #163f68;
	--color-message-red: #f8d8d4;
	--color-on-message-red: #8e1b12;
	--color-message-green: #d9f0dc;
	--color-on-message-green: #1d5a28;
	--color-message-heart: #e0245e;
	--color-offline-backdrop: #1c2230a6;
	--color-offline-card: #ffffff;
	--color-offline-icon: #3a4150;
}

:root[data-theme="dark"] {
	color-scheme: dark;

	/* Page */
	--color-page: #0c0c0d;            /* near-black page; the panels on it are lifted (Sep 25) */
	--page-image-veil: color-mix(in srgb, var(--color-page) 93%, transparent);   /* picture at 7 % */
	--color-panel: #2a2a2e;
	--color-text: #f2f2f7;
	--color-accent: color-mix(in srgb, var(--brand) 78%, #ffffff);  /* BRAND, lifted for dark */

	/* Banner */
	--color-banner: #33363c;          /* graphite, lifted off the (lighter, Sep 25) dark container */
	--color-banner-strong: var(--color-banner);
	--color-banner-shadow: #00000066;
	--color-on-banner: #ffffff;
	--color-on-banner-soft: #e0e3e7;
	--color-banner-text: var(--color-nav-item-icon);
	--color-banner-name: #ffffff;
	--color-banner-soft: #c8d5db;
	--color-banner-menu-icon: #ffffff;
	--color-banner-hover: #ffffff1f;

	/* Navigation */
	--color-nav: #1c1c1f;
	--color-nav-border: #ffffff1f;    /* on a black page the bar needs a faint edge */
	--color-nav-shadow: #00000080;
	--color-nav-item: #ffffff00;
	--color-nav-item-hover: #ffffff1a;
	--color-nav-item-press: #ffffff2e; /* unpin button under the mouse */
	--color-nav-divider: #ffffff12;   /* line above the unpin button (pinned nav) */
	--color-nav-active-pinned: #dcdce1;
	--color-nav-item-text: #ebebf0;
	--color-nav-item-icon: #98989f;
	--color-nav-active: #ebebf0;
	--color-nav-active-text: #0b0b0c;
	--color-nav-active-shadow: #00000000;
	--color-nav-tab-arrow: #aeaeb2;
	--color-nav-dim: #0000001f;
	--blur-darken: 10%;

	/* Settings pop-up */
	--color-sheet: #2a2a2e;
	--color-sheet-backdrop: #00000099;
	--color-group: #36363b;
	--color-group-hover: #404045;
	--color-separator: #45454a;
	--color-label: #ffffff;
	--color-label-secondary: #98989f;
	--color-fill: #48484a;
	--color-week-pill: color-mix(in oklab, var(--color-button-primary) 45%, #55585e);
	--color-on-week-pill: #ffffff;
	--color-hours-field: #45454a;
	--color-uurbon-value: #d8d8dd;
	--color-close: #48484a;
	--color-close-hover: #57575a;
	--color-close-icon: #f2f2f7;
	--color-switch-off: #4a4a4e;
	--color-switch-knob: #ffffff;
	--color-switch-company: #485d70;
	--color-destructive: #ff453a;
	--color-delete-soft: #4a4a4e;
	--color-delete-soft-hover: #58585c;
	--color-delete-soft-icon: #e5e5ea;

	/* Pages and cards */
	--color-card: #36363b;
	--color-card-hover: #3d3d42;
	--color-card-shadow: #00000000;
	--color-panel-title: #e5e5ea;
	--color-text-secondary: #98989f;
	--color-placeholder: #6c6c70;
	--color-link: color-mix(in srgb, var(--brand) 45%, #ffffff);     /* BRAND */
	--color-error: #ff6961;
	--color-success: #6fd08a;
	--color-filter-track: #36363b;
	--color-filter-active: #5a5a5f;
	--color-filter-shadow: #00000066;
	--color-menu: #424247;
	--color-menu-hover: #4a4a4f;
	--color-menu-shadow: #00000080;
	--color-sort-direction: #58585c;
	--color-sort-direction-hover: #666669;
	--color-tile: #36363b;
	--color-tile-separator: #45454a;
	--color-tile-item: #414146;
	--color-tile-item-hover: #4a4a4f;
	--color-field: #45454b;             /* a step up from the tile, like white on grey */
	--color-field-border: #45454b;
	--color-field-focus: color-mix(in srgb, var(--color-accent) 40%, transparent); /* BRAND */
	--color-avatar: color-mix(in srgb, var(--brand) 45%, #1c1c1e);   /* BRAND */
	--color-avatar-text: color-mix(in srgb, var(--brand) 25%, #ffffff); /* BRAND */
	--color-photo-backdrop: #000000cc;
	--color-photo-shadow: #00000099;
	--color-agenda: #414146;          /* the dark theme's "white": one step up from a card */
	--color-day-today: var(--color-accent);                              /* BRAND */
	--color-on-day-today: #ffffff;
	--color-day-booked: color-mix(in srgb, var(--brand) 55%, #414146);  /* BRAND */
	--color-on-day-booked: #ffffff;
	--color-day-past: color-mix(in srgb, var(--brand) 8%, #505156);
	--color-on-day-past: #c6c8cd;
	--color-day-weekend: #6b6f77;
	--color-expired: #ff9a92;
	--color-soon: #f2b84b;
	--color-vehicle-photo: #3a3d42;
	--color-vehicle-photo-icon: #9a9aa0;
	--color-size: #414146;
	--color-size-hover: #4a4a4f;
	--color-size-text: #98989f;
	--color-badge-remove: #4a4a4e;
	--color-badge-remove-hover: #58585c;
	--color-on-badge-remove: #e5e5ea;
	--color-user-check-ok: #5ccf7f;
	--color-user-check-warn: #98989d;
	--color-user-check-bad: #ff7a70;
	--color-user-check-extra: #6c6c70;
	--color-cert-required: #4a2522;
	--color-on-cert-required: #ff9a92;
	--color-cert-recommended: #1f3350;
	--color-on-cert-recommended: #8fb8f0;
	--color-cert-info: #8fb0e0;
	--color-info: #4f7fbf;
	--color-on-info: #ffffff;
	--color-you: #3e5a47;
	--color-on-you: #bfe3ca;
	--color-user-row: #2f2f33;
	--color-info-tip: #283444;
	--color-on-info-tip: #c3d5ef;
	--color-cert-pending: #3d2e14;
	--color-on-cert-pending: #f0b04a;
	--color-req-track: #2c2c2f;
	--color-req-active: #48484d;
	--color-user-summary: #98989f;
	--color-user-row-top: #f5f5f7;
	--color-user-row-bottom: #d1d1d6;
	--color-user-head: #27313f;
	--color-user-head-active: #33445a;
	--color-on-user-head: #8fb0dc;
	--color-on-user-head-active: #c3d5ef;
	--color-user-pinned: #ff7a70;
	--color-scroll-track: #2c2c30;
	--color-scroll-thumb: #48484d;
	--color-pin-resizer: #5c5c62;
	--color-company-photo-button: #4a4a4e;
	--color-company-photo-button-hover: #58585c;
	--color-on-company-photo-button: #e5e5ea;
	--color-button-destructive: #d0352b;
	--color-button-destructive-hover: #e04a40;
	--color-on-button-destructive: #ffffff;
	--color-button-primary: color-mix(in srgb, var(--brand) 82%, #ffffff);   /* BRAND */
	--color-button-primary-hover: color-mix(in srgb, var(--brand) 72%, #ffffff); /* BRAND */
	--color-on-button-primary: #ffffff;
	--color-button-secondary: #414146;
	--color-button-secondary-hover: #4a4a4f;
	--color-project-add: color-mix(in srgb, var(--brand) 82%, #ffffff);   /* BRAND */
	--color-on-project-add: #ffffff;
	--color-project-badge: #45454b;
	--color-on-project-badge: #d6e2ea;
	--color-button-pdf: #48484a;
	--color-button-pdf-hover: #57575a;
	--color-on-button-pdf: #f2f2f7;
	--color-panel-button: #36363b;
	--color-panel-button-hover: #404045;
	--color-panel-button-icon: #d1d1d6;
	--color-on-button-secondary: #f2f2f7;
	--color-toast: #f2f2f7;
	--color-on-toast: #1c1c1e;
	--color-toast-shadow: #00000080;

	--color-mark-draft: #5c6069;
	--color-mark-waiting: #8fc3ff;
	--color-mark-ok: #6ee78e;
	--color-mark-project: #D0D5DC;
	--color-mark-denied: #e96d62;

	/* Status chips: the same colours as in the light theme (Sep 25). The dark versions
	   turned them inside out (dark fill, bright text); the chip should stay the
	   chip it is, with its text a darker shade of its own fill. */
	--color-status-draft: #e0e3ea;
	--color-on-status-draft: #4c515c;

	--color-parking: #3b3e45;
	--color-on-parking: #c3c7d0;
	--color-status-request: #fff0d6;
	--color-on-status-request: #8a4b00;
	--color-status-submitted: #dfe6ee;
	--color-on-status-submitted: #3f5569;
	--color-status-accepted: #a0ddb0;
	--color-on-status-accepted: #3f8151;
	--color-status-in-progress: #ddf2e3;
	--color-on-status-in-progress: #1d6b33;
	--color-status-completed: #ebebef;
	--color-on-status-completed: #58585d;
	--color-status-denied: #e4908a;
	--color-on-status-denied: #722420;

	--color-attention: #f6d3cf;
	--color-on-attention: #8e1b12;

	--color-message-blue: #1b3148;
	--color-on-message-blue: #a9cdf2;
	--color-message-red: #4a1d1a;
	--color-on-message-red: #ffaaa3;
	--color-message-green: #1b3a22;
	--color-on-message-green: #9ee0aa;
	--color-message-heart: #ff5c86;
	--color-offline-backdrop: #000000b8;
	--color-offline-card: #3a3a3e;
	--color-offline-icon: #d1d1d6;
}

/* ---------- Layout sizes ---------- */
/* Shared by the white top area and the page panel, so they always line up. */
:root {
	/* Blue banner is 46rem wide with a 1.25rem radius. The white area around it leaves
	   .6rem on every side; its radius was 1.25 + .6 so the corners ran parallel, and was
	   taken down a touch (1.85 → 1.75) on Sep 23 for a less bubbly look. */
	--app-width: 47.2rem;
	--radius-panel: 1.75rem;
	/* Panels in the content area. Half the radius while the white top area is snapped
	   to the screen edges (phones); the full radius once it floats (see the end of this file). */
	--radius-content: calc(var(--radius-panel) / 2);

	/* Tiles inside a page: at least --tile-min wide; columns are added while they fit.
	   The page is as wide as 3 columns of --tile-max, fullscreen as wide as 5. */
	--tile-min: 17rem;
	--tile-max: 22rem;
	--tile-gap: 1rem;
	--page-width: calc(3 * var(--tile-max) + 2 * var(--tile-gap) + 2rem);
	--fullscreen-width: calc(5 * var(--tile-max) + 4 * var(--tile-gap));
}

/* ---------- Theme switch ---------- */
/* Switching theme changes every color at the same moment, then the whole screen
   crossfades from the old to the new colors (View Transitions API).
   While switching, all other transitions are off so nothing fades at its own pace. */
.theme-switching *,
.theme-switching *::before,
.theme-switching *::after,
.theme-switching ::backdrop {
	transition: none !important;
}

::view-transition-old(root),
::view-transition-new(root) {
	animation-duration: .3s;
	animation-timing-function: ease-in-out;
}

/* ---------- Base ---------- */
* {
	box-sizing: border-box;
}

/* No visible scrollbars anywhere (everything still scrolls with wheel, touch and keys) */
* {
	scrollbar-width: none;
}

*::-webkit-scrollbar {
	display: none;
	width: 0;
	height: 0;
}

/* The hidden attribute always wins, also on elements that set their own display */
[hidden] {
	display: none !important;
}

/* Every popover here (menus, calendars, suggestion lists) is placed by script with top
   and left. The browser's own popover style pins all four sides (inset: 0) and relies on
   height: fit-content to stay small; Safari on iPhone stretched the avatar menu from the
   top of the screen to the bottom (Sep 25). Only top/left count now, so a popover is
   always as tall as what is in it. */
[popover] {
	inset: auto;
	height: auto;
}

body {
	margin: 0;
	/* Apple devices use SF Pro (system font), everything else falls back to Inter */
	font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Inter", "Segoe UI", sans-serif;
	-webkit-font-smoothing: antialiased;
	color: var(--color-on-banner-soft);
	/* The banner's colour, not the grey (Sep 25): this is the colour the browser gives
	   the whole canvas, and Safari on iPhone paints the strip behind the clock and the
	   Dynamic Island from it. It follows the banner colour set on App-beheer. The grey
	   and the wallpaper are drawn on top by body::before, so the page looks the same. */
	background: var(--color-banner);
	/* Page = top panel + content area filling the rest of the screen */
	display: flex;
	flex-direction: column;
	height: 100vh;
	height: 100dvh;
	overflow: hidden;
}

button {
	margin: 0;
	padding: 0;
	border: 0;
	font: inherit;
	color: inherit;
	background: none;
	cursor: pointer;
}

/* ---------- No focus rings ---------- */
/* Nothing in this app draws a box around whatever was last tapped. It is used on a
   phone with gloves on, where a ring around a field reads as something having gone
   wrong rather than as help. Fields say it with their own border colour instead.
   This also switches off the browser's own ring, which would otherwise step in where
   ours used to be — so there is nothing on screen showing where keyboard focus is.
   Deleting this block brings it back everywhere at once. */
*:focus,
*:focus-visible {
	outline: none;
}

svg {
	display: block;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.74;
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* ---------- Top area (banner + nav) ---------- */
/* White panel with rounded bottom corners around the banner and the nav, sitting on the
   wallpaper. Its height follows its content. On wide screens it floats and gets all
   four corners (end of this file). On phones in portrait, where the banner snaps to the
   screen edges, there is no panel at all: the banner and nav stand straight on the
   wallpaper, which gives the list more room (Sep 25 — the panel was missed on
   desktop but not on the phone). */
.top {
	flex-shrink: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: .6rem;
	padding: .6rem 1rem;
	background: var(--color-panel);
	border-radius: 0 0 var(--radius-panel) var(--radius-panel);
}

/* ---------- Banner ---------- */
/* Since Sep 25: graphite, the name in white, the menu icon and the date in a light
   blue-grey, and the company logo as a square on the right, from the top of the banner
   to the bottom (inset a little, with a radius that runs parallel to the banner's corner).
     column 1: avatar + name (row 1), menu + date (row 2)   column 2: logo
   The logo's size follows from the left column's height, which is fixed: avatar +
   row gap + menu 1.5rem (--banner-content). The avatar is a little smaller here than
   elsewhere (1.84rem, 8% under the usual 2rem), and the row gap is wide enough that
   the menu button's hover patch stays clear of it (Sep 25). */
.banner {
	--banner-avatar: 1.84rem;
	--banner-pad-y: .5rem;
	--banner-gap-y: .45rem;
	--banner-content: calc(var(--banner-avatar) + var(--banner-gap-y) + 1.5rem);
	--banner-inset: .3rem;          /* logo to the banner's edge */
	--banner-radius: 1.1rem;
	--banner-logo: calc(var(--banner-content) + 2 * (var(--banner-pad-y) - var(--banner-inset)));
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	grid-template-rows: var(--banner-avatar) 1.5rem;
	align-items: center;
	gap: var(--banner-gap-y) .75rem;
	width: min(100%, 46rem);
	padding: var(--banner-pad-y) var(--banner-inset) var(--banner-pad-y) 1.1rem;
	border-radius: var(--banner-radius);
	corner-shape: squircle;
	color: var(--color-banner-text);
	background: var(--color-banner);
	box-shadow: 0 0 0 1px var(--color-nav-border);   /* no drop shadow (Sep 25) */
}

.banner-user {
	grid-column: 1;
	grid-row: 1;
	min-width: 0;
	display: flex;
	align-items: center;
	gap: .55rem;
	color: var(--color-banner-name);
	font-size: .95rem;
	font-weight: 600;
	letter-spacing: -.01em;
}

.user-name {
	overflow: hidden;
	white-space: nowrap;
}

.banner .avatar {
	width: var(--banner-avatar);
	height: var(--banner-avatar);
	font-size: .68rem;
}

.avatar {
	flex-shrink: 0;
	display: grid;
	place-items: center;
	width: 2rem;
	height: 2rem;
	border-radius: 50%;
	font-size: .72rem;
	font-weight: 600;
	color: var(--color-banner-strong);
	background: var(--color-on-banner);
}

/* The company logo: square, top to bottom. A white logo on a see-through background
   (image/logo-transparent.png), so it stands straight on the banner colour. */
.banner-logo {
	grid-column: 2;
	grid-row: 1 / 3;
	display: block;
	width: var(--banner-logo);
	height: var(--banner-logo);
	margin-block: calc(var(--banner-inset) - var(--banner-pad-y));
	/* The picture has less empty room on its right (74 of 1200 px) than under the
	   text (130 px), so the white stood closer to the banner's edge than to its top and
	   bottom. This pushes it in by the difference, at every banner size (Sep 25). */
	margin-right: calc(var(--banner-logo) * .047);
	object-fit: contain;
	border-radius: calc(var(--banner-radius) - var(--banner-inset));
	corner-shape: squircle;
}

/* Safari draws plain round corners, which look bigger at the same number */
@supports not (corner-shape: squircle) {
	.banner-logo {
		border-radius: .55rem;
	}
}

.banner-menu {
	grid-column: 1;
	grid-row: 2;
	justify-self: start;
	/* A little room around the icon for the hover patch, taken back with negative
	   margins so the icon stays where it was: centred under the avatar,
	   (avatar − icon 1.5rem) / 2 from the left, minus the padding */
	padding: .25rem;
	margin: -.25rem 0 -.25rem calc((var(--banner-avatar) - 1.5rem) / 2 - .25rem);
	border-radius: .6rem;
	color: var(--color-banner-menu-icon);
	transition: background-color .15s ease-in-out, color .15s ease-in-out, scale .1s ease-in-out;
}

/* It is a button: a soft light patch and white lines under the mouse, and a small
   press when clicked (Sep 25) */
.banner-menu:hover {
	color: var(--color-banner-name);
	background: var(--color-banner-hover);
}

.banner-menu:active {
	scale: .92;
}

.banner-menu svg {
	width: 1.5rem;
	height: 1.5rem;
	stroke-width: 2.4;   /* a heavier line than the other icons (Sep 25) */
}

/* Under the name, starting where the name starts: the avatar + the .55rem gap
   between avatar and name (.banner-user) */
.banner-date {
	grid-column: 1;
	grid-row: 2;
	justify-self: start;
	min-width: 0;
	margin-left: calc(var(--banner-avatar) + .55rem);
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
	font-size: .82rem;
	font-weight: 600;
	color: var(--color-banner-soft);
}

/* ---------- Navigation ---------- */
/* A slim near-black pill with only icons in it; the current page is a white pill
   inside it (Sep 25, from reference shots). Compact on purpose: every rem it
   saves is list on a phone. Opening it still turns it into the list with labels. */

/* The wrapper keeps the collapsed height, so the open nav overlaps the content. */
.nav-wrap {
	--nav-pad: .25rem;             /* bar around the buttons */
	--nav-button: 2.1rem;          /* height of a page button */
	--nav-height: calc(var(--nav-button) + 2 * var(--nav-pad));
	position: relative;
	flex-shrink: 0;
	width: 100%;
	height: var(--nav-height);
}

/* With the tab under the nav (phones) nothing extra is reserved: the tab hangs over the
   top of the page panel a little, so the nav is as far from the panel as it is from
   the banner (Sep 25) */

/* Holds the nav (centered on its own) and the round expand button, which floats
   to the right of it without affecting the centering.
   Only the nav, button and tab catch clicks: taps next to them reach the backdrop,
   so tapping anywhere outside the open menu closes it. */
.nav-row {
	position: relative;
	z-index: 2;
	display: flex;
	justify-content: center;
	max-width: 100%;
	pointer-events: none;
}

.nav-stack {
	pointer-events: none;
}

.nav,
.nav-side,
.nav-tab {
	pointer-events: auto;
}

.nav-stack {
	position: absolute;
	z-index: 10;
	top: 0;
	left: 0;
	right: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
}

.nav {
	/* Width follows the number of pages (--nav-count, set by script.js on .nav-wrap).
	   It shrinks when the screen is too narrow; the page buttons shrink with it. */
	--nav-item-width: 2.7rem;
	--nav-gap: .15rem;
	--nav-width: calc(var(--nav-count, 7) * var(--nav-item-width)
		+ (var(--nav-count, 7) - 1) * var(--nav-gap) + 2 * var(--nav-pad));
	position: relative;
	z-index: 2;
	flex: 0 1 auto;
	min-width: 0;
	width: var(--nav-width);
	padding: var(--nav-pad);
	overflow: hidden;
	border-radius: calc(var(--nav-height) / 2);
	background: var(--color-nav);
	box-shadow: 0 0 0 1px var(--color-nav-border);
	transition: border-radius .3s ease-in-out;
}

.nav ul {
	display: grid;
	grid-template-columns: repeat(var(--nav-count, 7), minmax(0, 1fr));
	gap: var(--nav-gap);
	margin: 0;
	padding: 0;
	list-style: none;
}

.nav li {
	min-width: 0;
	container-type: inline-size;
}

.nav a {
	display: flex;
	align-items: center;
	height: var(--nav-button);
	/* centers the icon while collapsed */
	padding-left: calc(50cqw - .6rem);
	overflow: hidden;
	white-space: nowrap;
	/* A pill inside the pill */
	border-radius: calc(var(--nav-button) / 2);
	color: var(--color-nav-item-text);
	background: var(--color-nav-item);
	text-decoration: none;
	transition: background-color .2s ease-in-out, color .2s ease-in-out,
		padding-left .3s ease-in-out;
}

.nav a:hover {
	background: var(--color-nav-item-hover);
}

/* Current page: its icon and label turn dark; the white pill behind it is
   .nav-indicator, one pill that slides from page to page */
.nav a.active {
	color: var(--color-nav-active-text);
	background: transparent;
	cursor: default;
}

.nav ul {
	position: relative;
	z-index: 1;
}

/* The white "you are here" pill. One element for the whole bar, placed under the
   current page's button by placeNavIndicator() in script.js, so a page change slides
   it across instead of switching one button off and the next on. It follows the
   buttons when the bar opens into the list, too. */
.nav-indicator {
	position: absolute;
	top: 0;
	left: 0;
	z-index: 0;
	width: 0;
	height: 0;
	border-radius: calc(var(--nav-button) / 2);
	background: var(--color-nav-active);
	box-shadow: 0 1px 3px var(--color-nav-active-shadow);
	pointer-events: none;
	transition: transform .38s cubic-bezier(.3, .8, .25, 1), width .38s cubic-bezier(.3, .8, .25, 1),
		opacity .2s ease-in-out;
}

/* Placed without sliding: first draw, a resize, the bar opening or closing */
.nav-indicator.no-slide {
	transition: none;
}

.nav .icon {
	flex-shrink: 0;
	color: var(--color-nav-item-icon);
	width: 1.2rem;
	height: 1.2rem;
	stroke-width: 1.9;
	transition: color .2s ease-in-out;
}

.nav a:hover .icon {
	color: var(--color-nav-item-text);
}

.nav a.active .icon {
	color: var(--color-nav-active-text);
	stroke-width: 2.1;
	transition-delay: .08s;
}

.nav .label {
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	padding-right: .5rem;
	margin-left: .7rem;
	font-size: .9rem;
	font-weight: 500;
	letter-spacing: -.01em;
	opacity: 0;
	transition: opacity .12s ease-in-out;
}

/* Tab behind the nav: its top is tucked under the bar, only the arrow hangs out */
.nav-tab {
	position: relative;
	z-index: 1;
	margin-top: -.8rem;
	padding: .8rem .9rem 0;
	border-radius: 0 0 .75rem .75rem;
	color: var(--color-nav-tab-arrow);
	background: var(--color-nav);
	box-shadow: 0 0 0 1px var(--color-nav-border);
}

.nav-tab .arrow {
	width: .95rem;
	height: .95rem;
	stroke-width: 2.6;
	transition: rotate .3s ease-in-out;
}

/* Open state: vertical list with labels */
.nav.open {
	border-radius: 1.25rem;
}

.nav.open ul {
	grid-template-columns: minmax(0, 1fr);
}

.nav.open a {
	padding-left: .75rem;
}

.nav.open .label {
	opacity: 1;
	transition: opacity .2s ease-in-out .1s;
}

.nav-stack.open .nav-tab .arrow {
	rotate: 180deg;
}

/* Round expand button, floating to the right of the nav: the bar's own colour, so it
   reads as part of it while standing apart */
.nav-side {
	position: absolute;
	top: calc(var(--nav-height) / 2);
	left: calc(100% + .4rem);
	translate: 0 -50%;
	display: grid;
	place-items: center;
	width: calc(var(--nav-height) - .35rem);   /* a little smaller than the bar is tall */
	height: calc(var(--nav-height) - .35rem);
	border-radius: 50%;
	color: var(--color-nav-item-icon);
	background: var(--color-nav);
	box-shadow: 0 0 0 1px var(--color-nav-border);
	transition: color .2s ease-in-out, opacity .2s ease-in-out,
		scale .2s ease-in-out, visibility .2s;
}

/* The pin button: a second round button, right of the expand button. Only where the
   nav can be pinned (html.pin-available, set by script.js: desktop, tablet in landscape) */
.nav-pin {
	left: calc(100% + .4rem + var(--nav-height) - .35rem + .3rem);
	display: none;
}

.pin-available .nav-pin {
	display: grid;
}

.nav-pin svg,
.nav-unpin svg {
	stroke-width: 2 !important;
}

/* Menu open: the button fades away (the nav doesn't move) */
.nav-stack.open .nav-side {
	opacity: 0;
	scale: .7;
	visibility: hidden;
}

.nav-side:hover {
	color: var(--color-nav-item-text);
}

.nav-side svg {
	width: 1.05rem;
	height: 1.05rem;
	stroke-width: 2.4;
}

/* Which expand control is used (data-toggle on .nav-wrap, set by script.js):
   "button" = round button on the right, "tab" = tab under the nav (phones with many pages) */
.nav-wrap[data-toggle="tab"] .nav-side,
.nav-wrap:not([data-toggle="tab"]) .nav-tab {
	display: none;
}

/* ---------- Content area ---------- */
/* Gray background under the top panel, fills the rest of the screen.
   The page panel inside fills it, with a margin all around; the panel body scrolls.
   Extra space at the top clears the nav tab that hangs below the top panel. */
.content {
	flex: 1;
	min-height: 0;
	display: flex;
	flex-direction: column;
	margin: 0;
	padding: .6rem .75rem max(.75rem, env(safe-area-inset-bottom));
	overflow: hidden;
	color: var(--color-text);
	/* See-through, so the wallpaper on the body shows in the gaps around the panels */
	background: transparent;
}

/* ---------- Wallpaper ---------- */
/* A fixed layer rather than background-attachment: fixed, which Safari on iOS does not
   handle. It sits behind everything the app draws (z-index -1) and holds the page grey
   itself, with the picture on top of it (the canvas underneath is the banner colour, for
   the iPhone's status bar). The dark theme turns the picture down with a veil of the
   page colour over it, rather than with opacity, which would let the banner colour
   through. */
body::before,
.auth::before {
	content: "";
	position: fixed;
	inset: 0;
	z-index: -1;
	background:
		linear-gradient(var(--page-image-veil), var(--page-image-veil)),
		var(--page-image) center / cover no-repeat,
		var(--color-page);
	pointer-events: none;
}

/* ---------- Layer behind the open nav ---------- */
/* Covers the page (below the nav) so nothing else can be clicked while the nav is open.
   Set --color-nav-dim to e.g. #0000001f to also dim the page. */
.nav-backdrop {
	position: fixed;
	inset: 0;
	z-index: 5;
	pointer-events: none;
	background: #00000000;
	-webkit-backdrop-filter: blur(0) saturate(1);
	backdrop-filter: blur(0) saturate(1);
	transition: background-color .3s ease-in-out, backdrop-filter .3s ease-in-out;
}

/* Open nav: the page behind it gets a soft blur and loses most of its colour,
   so the open menu is the only thing still drawn in full colour */
.nav-backdrop.show {
	pointer-events: auto;
	background: var(--color-nav-dim);
	-webkit-backdrop-filter: blur(3px) saturate(.6);
	backdrop-filter: blur(3px) saturate(.6);
}

/* ---------- Settings pop-up ---------- */
/* Based on the iOS Settings app. Sizes are iOS points (1pt = 1px):
   rows 52px, side padding 16px, groups 35px apart, group radius 26px. */
.settings {
	width: min(calc(100% - 2rem), 24rem);
	max-height: calc(100% - 2rem);
	padding: 0;
	border: 0;
	border-radius: 2rem;
	corner-shape: squircle;
	color: var(--color-label);
	background: var(--color-sheet);
	opacity: 0;
	scale: .96;
	transition: opacity .2s ease-in-out, scale .2s ease-in-out,
		overlay .2s allow-discrete, display .2s allow-discrete;
}

.settings[open] {
	opacity: 1;
	scale: 1;
}

@starting-style {
	.settings[open] {
		opacity: 0;
		scale: .96;
	}
}

/* Behind a pop-up: the page dims and gets a very soft blur */
.settings::backdrop {
	background: #00000000;
	-webkit-backdrop-filter: blur(0) saturate(1);
	backdrop-filter: blur(0) saturate(1);
	transition: background-color .2s ease-in-out, backdrop-filter .2s ease-in-out,
		overlay .2s allow-discrete, display .2s allow-discrete;
}

.settings[open]::backdrop {
	background: var(--color-sheet-backdrop);
	-webkit-backdrop-filter: blur(3px) saturate(.6);
	backdrop-filter: blur(3px) saturate(.6);
}

@starting-style {
	.settings[open]::backdrop {
		-webkit-backdrop-filter: blur(0) saturate(1);
		backdrop-filter: blur(0) saturate(1);
		background: #00000000;
	}
}

.settings-inner {
	padding: 1rem 1rem 1.25rem;
	font-size: 1.0625rem;
	line-height: 1.375rem;
}

/* Header: round close button on the left, title centered */
.settings-head {
	display: grid;
	grid-template-columns: 2.75rem 1fr 2.75rem;
	align-items: center;
	margin-bottom: 1.25rem;
}

.settings-head h2 {
	grid-column: 2;
	grid-row: 1;
	margin: 0;
	font-size: 1.0625rem;
	font-weight: 600;
	text-align: center;
	color: var(--color-label);
}

.settings-close {
	grid-column: 1;
	grid-row: 1;
	display: grid;
	place-items: center;
	width: 2.75rem;
	height: 2.75rem;
	border-radius: 50%;
	color: var(--color-close-icon);
	background: var(--color-close);
	transition: background-color .2s ease-in-out;
}

.settings-close:hover {
	background: var(--color-close-hover);
}

.settings-close svg {
	width: 1.25rem;
	height: 1.25rem;
	stroke-width: 2.6;
}

/* Section header above a group */
.settings-label {
	margin: 2.1875rem 0 .375rem;
	padding: 0 1rem;
	font-size: 1.0625rem;
	font-weight: 600;
	line-height: 1.375rem;
	color: var(--color-label-secondary);
}

.settings-head + .settings-label {
	margin-top: 0;
}

/* Group with rows */
/* Rounded, but not a bubble: these are sheets of paper with a soft corner. */
.settings-group {
	overflow: hidden;
	border-radius: 1.15rem;
	background: var(--color-group);
}

.settings-group-spaced {
	margin-top: 2.1875rem;
}

.settings-row {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	width: 100%;
	min-height: 3.25rem;
	padding: 0 1rem;
	font: inherit;
	text-align: left;
	color: var(--color-label);
	background: var(--color-group);
}

/* Separator between rows, inset 16px on both sides */
.settings-row + .settings-row::before {
	content: "";
	position: absolute;
	top: 0;
	left: 1rem;
	right: 1rem;
	height: 1px;
	background: var(--color-separator);
}

.settings-row-toggle {
	padding-right: .875rem;
	cursor: pointer;
}

/* Switch (iOS style, theme blue when on) */
.switch {
	appearance: none;
	position: relative;
	flex-shrink: 0;
	width: 4rem;
	height: 1.75rem;
	margin: 0;
	border-radius: 1rem;
	background: var(--color-switch-off);
	cursor: pointer;
	transition: background-color .25s ease-in-out;
}

.switch::before {
	content: "";
	position: absolute;
	top: .1875rem;
	left: .1875rem;
	width: 2.125rem;
	height: 1.375rem;
	border-radius: .6875rem;
	background: var(--color-switch-knob);
	transition: translate .25s ease-in-out;
}

.switch:checked {
	background: var(--color-accent);
}

.switch:checked::before {
	translate: 1.5rem 0;
}

/* Segmented control (language): compact, sits on the right of its row */
.segmented {
	display: flex;
	gap: .125rem;
}

.segmented label {
	position: relative;
}

.segmented input {
	position: absolute;
	opacity: 0;
	pointer-events: none;
}

.segmented span {
	display: block;
	min-width: 2.75rem;
	padding: .3125rem .625rem;
	border-radius: 1rem;
	font-size: .9375rem;
	font-weight: 500;
	line-height: 1.25rem;
	text-align: center;
	color: var(--color-label-secondary);
	cursor: pointer;
	transition: background-color .2s ease-in-out, color .2s ease-in-out;
}

.segmented span:hover {
	color: var(--color-label);
}

.segmented input:checked + span {
	font-weight: 600;
	color: var(--color-label);
	background: var(--color-fill);
}

/* Log out row: centered, iOS red */
.logout {
	justify-content: center;
	font-weight: 400;
	color: var(--color-destructive);
}

.logout:hover {
	background: var(--color-group-hover);
}

/* ---------- Pages (panels) ---------- */
/* Full width on phones; on wide screens room for 3 columns of tiles (--page-width) */
.content-inner {
	flex: 1;
	min-height: 0;
	display: flex;
	flex-direction: column;
	width: 100%;
	max-width: var(--page-width);
	margin: 0 auto;
}

.page {
	flex: 1;
	min-height: 0;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	border-radius: var(--radius-content);
	background: var(--color-panel);
}

.panel-head {
	flex-shrink: 0;
	display: flex;
	align-items: center;
	gap: .6rem;
	padding: 1.1rem 1rem .9rem 1.25rem;
}

.panel-title {
	flex: 1;
	min-width: 0;
	margin: 0;
	font-size: 1.45rem;
	font-weight: 700;
	letter-spacing: -.02em;
	line-height: 1.2;
	color: var(--color-panel-title);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.panel-body {
	flex: 1;
	min-height: 0;
	/* Never sideways. A closed menu is still laid out (it only fades), and one that
	   reached past the right edge made the whole list slide left and right under a
	   finger on iPhone (Users, Vehicles). */
	overflow-x: hidden;
	overflow-y: auto;
	overscroll-behavior: contain;
	padding: 0 1rem 1rem;
}

/* Round, soft fullscreen button in the panel header */
.fullscreen-button {
	flex-shrink: 0;
	display: grid;
	place-items: center;
	width: 2.5rem;
	height: 2.5rem;
	border-radius: 50%;
	color: var(--color-panel-button-icon);
	background: var(--color-panel-button);
	transition: background-color .2s ease-in-out;
}

.fullscreen-button:hover {
	background: var(--color-panel-button-hover);
}

.fullscreen-button svg {
	width: 1.15rem;
	height: 1.15rem;
	stroke-width: 2.1;
}

.fullscreen-button .icon-collapse,
.page.is-fullscreen .fullscreen-button .icon-expand {
	display: none;
}

.page.is-fullscreen .fullscreen-button .icon-collapse {
	display: block;
}

/* Fullscreen: the panel covers the whole screen, including banner and nav */
.page.is-fullscreen {
	position: fixed;
	inset: 0;
	z-index: 60;
	border-radius: 0;
	padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
}

.empty {
	margin: 2rem 0;
	text-align: center;
	color: var(--color-text-secondary);
}

/* ---------- Buttons ---------- */
.button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: .35rem;
	min-height: 2.75rem;
	padding: 0 1.1rem;
	border-radius: 1.375rem;
	font-size: 1rem;
	font-weight: 600;
	transition: background-color .2s ease-in-out, opacity .2s ease-in-out;
}

.button svg {
	width: 1.15rem;
	height: 1.15rem;
	stroke-width: 2.4;
}

.button:disabled {
	opacity: .5;
	cursor: default;
}

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

.button-primary:hover:not(:disabled) {
	background: var(--color-button-primary-hover);
}

.button-secondary {
	color: var(--color-on-button-secondary);
	background: var(--color-button-secondary);
}

.button-secondary:hover:not(:disabled) {
	background: var(--color-button-secondary-hover);
}

.button-small {
	min-height: 2.25rem;
	padding: 0 .95rem 0 .75rem;
	font-size: .9375rem;
}

.button-block {
	width: 100%;
	min-height: 3.25rem;
	border-radius: 1.625rem;
	font-size: 1.0625rem;
}

/* Just an icon, no word next to it: the + in a panel header. Wider than it is tall,
   so it still reads as a button rather than a dot. */
.button-icon {
	min-width: 3.25rem;
	padding: 0;
}

/* The + in the Assignments header: a wider pill, so it reads as the page's main
   button rather than as another round icon next to full screen */
.panel-head .button-icon.dropdown-button,
#assignment-new {
	min-width: 4.5rem;
	padding-inline: 1.1rem;
}

.button-icon svg {
	width: 1.3rem;
	height: 1.3rem;
}

/* A button that is also the thing that opens a menu. Two classes on purpose: the
   plain .dropdown-button further down the file sets the page's text colour, which
   would otherwise win over .button-primary and leave a black + on a blue pill. */
.button-primary.dropdown-button {
	color: var(--color-on-button-primary);
}

.button-secondary.dropdown-button {
	color: var(--color-on-button-secondary);
}

/* Small enough to sit inside a card without taking it over */
.button-compact {
	min-height: 2.1rem;
	padding: 0 .85rem;
	border-radius: 1.05rem;
	font-size: .875rem;
}

.button-compact.button-icon {
	min-width: 2.5rem;
	padding: 0;
}

.button-compact svg {
	width: 1.05rem;
	height: 1.05rem;
	stroke-width: 2;
}

/* The answer that can't be undone (deny a request, delete a photo) */
.button-destructive {
	color: var(--color-on-button-destructive);
	background: var(--color-button-destructive);
}

.button-destructive:hover:not(:disabled) {
	background: var(--color-button-destructive-hover);
}

/* "Are you sure?": no on the left, yes on the right, same width */
.confirm-actions {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: .6rem;
}

/* ---------- Filter (segmented control above a list) ---------- */
.filter {
	display: grid;
	grid-auto-columns: minmax(0, 1fr);
	grid-auto-flow: column;
	gap: .125rem;
	padding: .1875rem;
	margin-bottom: 1rem;
	border-radius: 1.25rem;
	background: var(--color-filter-track);
}

.filter label {
	position: relative;
}

.filter input {
	position: absolute;
	opacity: 0;
	pointer-events: none;
}

.filter label > span {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: .35rem;
	min-height: 2.25rem;
	padding: 0 .5rem;
	border-radius: 1.0625rem;
	font-size: .9375rem;
	font-weight: 500;
	color: var(--color-text);
	cursor: pointer;
	transition: background-color .2s ease-in-out, box-shadow .2s ease-in-out;
}

.filter input:checked + span {
	font-weight: 600;
	background: var(--color-filter-active);
	box-shadow: 0 1px 4px var(--color-filter-shadow);
}

.filter-count {
	font-size: .8125rem;
	font-weight: 600;
	color: var(--color-text-secondary);
}

/* ---------- Cards ---------- */
.card {
	position: relative;
	padding: 1rem 1.1rem;
	/* Sharper than it was (1.375rem, Sep 23); Safari has no squircle and gets a smaller
	   plain radius below, which reads the same */
	border-radius: 1rem;
	corner-shape: squircle;
	background: var(--color-card);
	box-shadow: 0 1px 3px var(--color-card-shadow);
}


.card-title {
	margin: 0;
	font-size: 1.0625rem;
	font-weight: 600;
	line-height: 1.3;
	letter-spacing: -.01em;
}

/* The title button covers the whole card, so the whole card is tappable */
.card-open {
	text-align: left;
}

.card-open::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: inherit;
}

.card-sub {
	margin: .2rem 0 0;
	font-size: .9375rem;
	color: var(--color-text-secondary);
}


/* Buttons inside the card sit above the tappable title layer */
.card-actions {
	position: relative;
	z-index: 1;
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: .5rem;
	margin-top: .9rem;
}

/* ---------- Status chips ---------- */
.chip {
	display: inline-block;
	flex-shrink: 0;
	padding: .2rem .6rem;
	border-radius: 1rem;
	font-size: .75rem;
	font-weight: 600;
	line-height: 1.1rem;
	white-space: nowrap;
}

/* Hour papers: a draft is quiet grey because nobody else has seen it yet, waiting is
   the same amber as a request, approved the same green as work in progress, rejected
   the same red as a denial. */
.chip-draft { color: var(--color-on-status-draft); background: var(--color-status-draft); }
.chip-submitted { color: var(--color-on-status-submitted); background: var(--color-status-submitted); }
.chip-approved { color: var(--color-on-status-in-progress); background: var(--color-status-in-progress); }
.chip-rejected { color: var(--color-on-status-denied); background: var(--color-status-denied); }

.chip-request { color: var(--color-on-status-request); background: var(--color-status-request); }
.chip-accepted { color: var(--color-on-status-accepted); background: var(--color-status-accepted); }
.chip-in_progress { color: var(--color-on-status-in-progress); background: var(--color-status-in-progress); }
.chip-completed { color: var(--color-on-status-completed); background: var(--color-status-completed); }
.chip-denied { color: var(--color-on-status-denied); background: var(--color-status-denied); }

/* ---------- People ---------- */
.crew {
	display: flex;
	flex-shrink: 0;
}

.crew .avatar + .avatar {
	margin-left: -.25rem;
}

.avatar-small {
	flex-shrink: 0;
	width: 1.75rem;
	height: 1.75rem;
	font-size: .6875rem;
	color: var(--color-avatar-text);
	background: var(--color-avatar);
	box-shadow: 0 0 0 2px var(--color-card);
}

.avatar-more {
	color: var(--color-text-secondary);
}

.person {
	display: flex;
	align-items: center;
	gap: .65rem;
	min-width: 0;
}

.person small {
	display: block;
	font-size: .8125rem;
	color: var(--color-label-secondary);
}

/* ---------- Sheets ---------- */
/* Other pop-ups (assignment details, forms) reuse the .settings pop-up styles above.
   .sheet only adds what is different. */
.sheet {
	width: min(calc(100% - 2rem), 30rem);
}

.sheet .settings-inner {
	overflow-y: auto;
	max-height: calc(100dvh - 2rem);
}

/* The content scrolls inside the pop-up; the rounded corners clip it */
.sheet {
	overflow: hidden;
}

/* Header (close, title, button) stays at the top while the content scrolls under it.
   It stretches over the pop-up's padding so nothing shows around it.
   Once scrolled a little (.is-scrolled, set in script.js) it turns see-through and blurs
   whatever passes under it (same color, not darker); the blur fades out below it (::after). */
.sheet {
	--sheet-bg: var(--color-sheet);
}

.sheet .settings-head {
	position: sticky;
	top: -1rem; /* sticky counts from inside the 1rem padding; this puts it at the very top edge */
	z-index: 2;
	margin: -1rem -1rem .5rem;
	padding: 1rem 1rem .75rem;
	background: var(--sheet-bg);
	transition: background-color .3s ease-in-out, backdrop-filter .3s ease-in-out;
}

.sheet .settings-head::after {
	content: "";
	position: absolute;
	top: 100%;
	left: 0;
	right: 0;
	height: 1.75rem;
	pointer-events: none;
	-webkit-backdrop-filter: blur(6px);
	backdrop-filter: blur(6px);
	-webkit-mask-image: linear-gradient(#000000, #00000000);
	mask-image: linear-gradient(#000000, #00000000);
	opacity: 0;
	transition: opacity .3s ease-in-out;
}

/* A little darker than the sheet colour, so the bottom edge of the blurred bar can be
   made out; without it the bar and the content below are the same brightness and the
   edge disappears. The sheet colour is darkened first and only then made see-through,
   which keeps this a single background-color. A tint layer on top would look the same
   but could not animate — background-image doesn't interpolate — so the change snapped
   in instead of fading. */
.sheet .is-scrolled > .settings-head {
	background-color: color-mix(in srgb,
		color-mix(in srgb, #000000 var(--blur-darken), var(--sheet-bg)) 70%,
		#00000000);
	-webkit-backdrop-filter: blur(14px);
	backdrop-filter: blur(14px);
}

.sheet .is-scrolled > .settings-head::after {
	opacity: 1;
}

.sheet .settings-head h2 {
	font-variant-numeric: tabular-nums;
}

.sheet-hero {
	padding: 0 1rem;
	margin-bottom: 1.5rem;
}

.sheet-title {
	margin: .6rem 0 .3rem;
	font-size: 1.375rem;
	font-weight: 700;
	line-height: 1.25;
	letter-spacing: -.015em;
}

.sheet-dates {
	display: flex;
	align-items: center;
	gap: .4rem;
	margin: 0;
	font-size: .9375rem;
	color: var(--color-label-secondary);
}

.sheet-dates svg {
	width: 1rem;
	height: 1rem;
}

.sheet-text {
	margin: 0;
	padding: .85rem 1rem;
	white-space: pre-line;
}

.sheet .settings-label {
	margin-top: 1.5rem;
}

.info-row {
	padding-block: .8rem;
}

.row-value {
	min-width: 0;
	text-align: right;
	overflow-wrap: anywhere;
	color: var(--color-label-secondary);
}

.row-link {
	color: var(--color-link);
	text-decoration: none;
}

.row-link:hover {
	text-decoration: underline;
}

.sheet-action {
	justify-content: center;
	gap: .45rem;
	color: var(--color-link);
}

.sheet-action svg {
	width: 1.05rem;
	height: 1.05rem;
	stroke-width: 2;
}

.sheet-action:hover {
	background: var(--color-group-hover);
}

.sheet-action-destructive {
	color: var(--color-destructive);
}

/* ---------- Form rows (iOS style) ---------- */
.field-row {
	position: relative;
	display: flex;
	align-items: center;
	gap: 1rem;
	min-height: 3.25rem;
	padding: 0 1rem;
	color: var(--color-label);
	background: var(--color-group);
}

.field-row + .field-row::before,
.field-row + .settings-row::before,
.settings-row + .field-row::before {
	content: "";
	position: absolute;
	top: 0;
	left: 1rem;
	right: 1rem;
	height: 1px;
	background: var(--color-separator);
}

.field-row > span {
	flex-shrink: 0;
}

.field-row input,
.field-row select,
.field-row textarea {
	flex: 1;
	min-width: 0;
	margin: 0;
	padding: 0;
	border: 0;
	outline: 0;
	font: inherit;
	color: var(--color-label);
	background: transparent;
}

.field-row input::placeholder,
.field-row textarea::placeholder {
	color: var(--color-placeholder);
}

/* Label on the left, value on the right (dates, selects) */
.field-row > span + input,
.field-row > span + select {
	text-align: right;
	color: var(--color-label-secondary);
}

.field-row select {
	cursor: pointer;
	text-align-last: right;
	appearance: none;
}

.field-row-text {
	align-items: flex-start;
	padding-block: .9rem;
}

.field-row textarea {
	resize: vertical;
	min-height: 4.5rem;
}

/* Checkbox rows (crew picker) */
.check-row {
	justify-content: space-between;
	padding-block: .55rem;
	cursor: pointer;
}

/* A plain circle instead of the browser's own box: grey while off, blue once the
   person is on the crew. No border, so it reads as a dot rather than a control. */
.check-row input {
	appearance: none;
	-webkit-appearance: none;
	flex: 0 0 auto;
	width: 1.375rem;
	height: 1.375rem;
	margin: 0;
	border: 0;
	border-radius: 50%;
	background: var(--color-switch-off);
	cursor: pointer;
	transition: background-color .2s ease-in-out;
}

.check-row input:checked {
	background: var(--color-accent);
}

.form-error {
	min-height: 1.375rem;
	margin: 1rem 1rem .5rem;
	font-size: .9375rem;
	color: var(--color-error);
}

.form-error:empty {
	margin-block: .75rem;
}

/* ---------- Page layout: columns of tiles ---------- */
/* A page body holds tiles (small panels) in columns; each column stacks tiles on top of
   each other. script.js (arrangeTiles) puts the tiles in .tile-col columns: as many as
   fit at --tile-min wide, at most --tile-cols (3 normally, 5 in fullscreen, 1 on phones).
   Each tile goes into the shortest column, so the columns stay even. */
.tiles {
	--tile-cols: 3;
	display: flex;
	align-items: flex-start;
	gap: var(--tile-gap);
}

.tile-col {
	flex: 1 1 0;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: var(--tile-gap);
}

/* Before arranging (and for a single message) everything simply stacks */
.tiles:not(:has(> .tile-col)) {
	flex-direction: column;
	align-items: stretch;
}

.page.is-fullscreen .tiles {
	--tile-cols: 5;
}

/* Fullscreen: tiles keep a maximum width; the content is centered */
.page.is-fullscreen .panel-head,
.page.is-fullscreen .panel-body {
	padding-inline: max(1rem, calc((100% - var(--fullscreen-width)) / 2));
}

/* ---------- Tiles ---------- */
.tile {
	padding: .9rem 1rem 1rem;
	border-radius: 1.25rem;
	corner-shape: squircle;
	color: var(--color-text);
	background: var(--color-tile);
}

.tile-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: .5rem;
	margin-bottom: .75rem;
}

.tile-title {
	margin: 0;
	font-size: 1rem;
	font-weight: 650;
	letter-spacing: -.01em;
	color: var(--color-panel-title);
}

.tile-count {
	margin-left: .35rem;
	font-weight: 500;
	color: var(--color-text-secondary);
}

.tile-note {
	margin: .75rem 0 0;
	font-size: .8125rem;
	line-height: 1.15rem;
	color: var(--color-text-secondary);
}

/* ---------- Info tips (infoTip in script.js, Oct 20) ---------- */
/* A small blue round button with a white "i" right after a title; its text opens in a
   lighter soft-blue bubble above the title (Oct 20: it opened below, over the rows), as
   wide as the title row so it never runs off a phone. Hover shows it on a computer; a
   tap opens and closes it. */
.tile-head:has(.info-tip) {
	position: relative;
	justify-content: flex-start;
	gap: .4rem;
}

.info-tip {
	display: inline-flex;
}

.info-tip-button {
	display: grid;
	flex-shrink: 0;
	place-items: center;
	width: 1.05rem;
	height: 1.05rem;
	padding: 0;
	border: 0;
	border-radius: 50%;
	color: var(--color-on-info);
	background: var(--color-info);
	cursor: help;
}

/* The "i" is drawn centred in its 24 × 24 box (INFO_TIP_ICON in script.js), so the box
   only has to sit in the middle of the circle */
.info-tip-button svg {
	display: block;
	width: .8rem;
	height: .8rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 3.2;
	stroke-linecap: round;
}

.info-tip-button svg circle {
	fill: currentColor;
	stroke: none;
}

/* A popover in the top layer (Oct 20), so nothing on the page can cut it off or cover
   it. placeInfoTip (script.js) sets its top, left and width; the browser's own popover
   look (centred, a border, margin) is taken off here. */
.info-tip-text {
	position: fixed;
	inset: auto;
	box-sizing: border-box;
	margin: 0;
	padding: .5rem .7rem;
	border: 0;
	border-radius: .7rem;
	corner-shape: squircle;
	font-size: .8125rem;
	font-weight: 500;
	line-height: 1.15rem;
	color: var(--color-on-info-tip);
	background: var(--color-info-tip);
	box-shadow: 0 .25rem .9rem rgb(0 0 0 / .1);
	pointer-events: none;
	opacity: 1;
	translate: 0 0;
	transition: opacity .15s ease-in-out, translate .15s ease-in-out;
}

/* Rises into place as it opens */
@starting-style {
	.info-tip-text:popover-open {
		opacity: 0;
		translate: 0 .2rem;
	}
}

/* ---------- Fields (label above the input) ---------- */
.field {
	display: block;
	min-width: 0;
}

.field + .field,
.field + .field-pair,
.field-pair + .field,
.field-pair + .field-pair {
	margin-top: .65rem;
}

.field-pair > .field {
	margin-top: 0;
}

.field-pair {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	gap: .6rem;
}

/* Short field first, long one second (postal code + city) */
.field-pair-short {
	grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
}

.field-label {
	display: block;
	margin: 0 0 .15rem .1rem;
	font-size: .8125rem;
	font-weight: 500;
	line-height: 1.1rem;
	color: var(--color-text-secondary);
}

.field-input {
	display: block;
	width: 100%;
	height: 2.4rem;
	margin: 0;
	padding: 0 .75rem;
	border: 1px solid var(--color-field-border);
	border-radius: .75rem;
	outline: 0;
	font: inherit;
	font-size: .9375rem;
	color: var(--color-text);
	background: var(--color-field);
	transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out;
}

.field-input::placeholder {
	color: var(--color-placeholder);
}

.field-input:focus {
	border-color: var(--color-accent);
}

/* Number inputs without the up/down arrows */
.field-input[type="number"] {
	appearance: textfield;
}

.field-input[type="number"]::-webkit-inner-spin-button,
.field-input[type="number"]::-webkit-outer-spin-button {
	appearance: none;
	margin: 0;
}

/* ---------- Date fields ---------- */
/* A field that opens our own calendar. It looks exactly like a text field until you
   tap it; the value lives in a hidden input behind it. */
.datefield {
	position: relative;
	min-width: 0;
}

.datefield-button {
	display: flex;
	align-items: center;
	gap: .5rem;
	width: 100%;
	height: 2.4rem;
	padding: 0 .75rem;
	border: 1px solid var(--color-field-border);
	border-radius: .75rem;
	corner-shape: squircle;
	font: inherit;
	font-size: .9375rem;
	text-align: left;
	color: var(--color-text);
	background: var(--color-field);
	transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out;
}

.datefield-button:hover {
	border-color: var(--color-day-booked);
}

.datefield-button[aria-expanded="true"] {
	border-color: var(--color-accent);
}

.datefield-button svg {
	flex-shrink: 0;
	width: 1.05rem;
	height: 1.05rem;
	color: var(--color-text-secondary);
}

.datefield-value {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.datefield-value.is-empty {
	color: var(--color-placeholder);
}

/* The compact version used for a period ("Van 21 sep tot 25 sep") */
.datefield-pill {
	flex: 0 0 auto;
	width: auto;
}

.datefield-pill .datefield-button {
	width: auto;
	min-width: 4.75rem;
	height: auto;
	padding: .25rem .7rem;
	border: 0;
	border-radius: 1rem;
	font-weight: 600;
	justify-content: center;
	color: var(--color-label);
	background: var(--color-fill);
}

.datefield-pill .datefield-button:hover {
	background: var(--color-close-hover);
}

/* ---------- The calendar pop-up ---------- */
/* A popover, so it draws above the pop-up it was opened from. */
.datepicker {
	position: fixed;
	width: 17rem;
	margin: 0;
	padding: .6rem;
	border: 0;
	border-radius: 1rem;
	corner-shape: squircle;
	color: var(--color-text);
	background: var(--color-menu);
	box-shadow: 0 10px 30px var(--color-menu-shadow);
}

.datepicker:popover-open {
	display: block;
}

.datepicker-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: .5rem;
	margin-bottom: .4rem;
}

.datepicker-month {
	font-size: .875rem;
	font-weight: 650;
}

.datepicker-arrow {
	display: grid;
	place-items: center;
	width: 1.75rem;
	height: 1.75rem;
	border-radius: .5rem;
	corner-shape: squircle;
	color: var(--color-text-secondary);
	transition: background-color .15s ease-in-out, color .15s ease-in-out;
}

.datepicker-arrow:hover {
	color: var(--color-text);
	background: var(--color-menu-hover);
}

.datepicker-arrow svg {
	width: 1.05rem;
	height: 1.05rem;
	stroke-width: 2.2;
}

.datepicker-weekdays,
.datepicker-grid {
	display: grid;
	grid-template-columns: repeat(7, 1fr);
	gap: .1rem;
}

.datepicker-weekdays span {
	display: grid;
	place-items: center;
	height: 1.35rem;
	font-size: .625rem;
	font-weight: 700;
	text-transform: uppercase;
	color: var(--color-placeholder);
}

.pick-cell {
	display: grid;
	place-items: center;
	height: 2rem;
	border-radius: .45rem;
	corner-shape: squircle;
	font-size: .8125rem;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	color: var(--color-text);
	transition: background-color .12s ease-in-out, color .12s ease-in-out;
}

.pick-cell.is-other {
	color: var(--color-placeholder);
	font-weight: 500;
}

.pick-cell:hover {
	background: var(--color-menu-hover);
}

/* The one outline left in the app, and it is not about selection: it marks today.
   Inset, so it draws inside the cell rather than around it. */
.pick-cell.is-today {
	outline: 1.5px solid var(--color-accent);
	outline-offset: -1.5px;
}

.pick-cell.is-selected {
	color: var(--color-on-day-today);
	background: var(--color-day-today);
}

.datepicker-foot {
	display: flex;
	justify-content: space-between;
	gap: .5rem;
	margin-top: .5rem;
	padding-top: .5rem;
	border-top: 1px solid var(--color-separator);
}

.datepicker-action {
	padding: .25rem .6rem;
	border-radius: .5rem;
	corner-shape: squircle;
	font-size: .8125rem;
	font-weight: 600;
	color: var(--color-link);
	transition: background-color .15s ease-in-out;
}

.datepicker-action:hover {
	background: var(--color-menu-hover);
}

/* ---------- Dropdown field (User / Users) ---------- */
/* A field that opens our own menu. It looks exactly like a text field until you tap it,
   and the arrow is ours, so iOS can't move it to the other side. */
.field-dropdown {
	position: relative;
	display: block;
}

.field-dropdown-button {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: .5rem;
	width: 100%;
	height: 2.4rem;
	padding: 0 .65rem 0 .75rem;
	border: 1px solid var(--color-field-border);
	border-radius: .75rem;
	font: inherit;
	font-size: .9375rem;
	font-weight: 400;
	text-align: left;
	color: var(--color-text);
	background: var(--color-field);
	transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out;
}


/* Hangs under the field, at least as wide as it, and wider when an option needs the
   room. Pinned to both edges (left: 0; right: 0) it was stuck at exactly the field's
   width, which clipped the tick after the current choice. */
.field-dropdown .dropdown-menu {
	top: calc(100% + .3rem);
	left: 0;
	right: auto;
	min-width: 100%;
	width: max-content;
	max-width: min(20rem, calc(100vw - 2rem));
	max-height: 15rem;
	overflow-y: auto;
}

.field-dropdown .dropdown-menu [role="option"] {
	white-space: normal;
}

/* A dropdown sitting on the right of a settings row (new assignment form) instead of
   filling a field: it takes the width its text needs and keeps the row's height. */
.field-row .field-dropdown-compact {
	flex: 0 1 auto;
	min-width: 0;
	/* Sits against the right edge of the row, where these rows keep their value */
	margin: -.25rem -.25rem -.25rem auto;
}

.field-row .field-dropdown-compact .field-dropdown-button {
	width: auto;
	height: 2.1rem;
	padding: 0 .45rem 0 .7rem;
}

/* ---------- Size buttons (clothing size) ---------- */
/* One round button per size. The one you picked is filled in, the rest are dimmed.
   Tapping the filled one clears the field again. */
.size-row {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	gap: .35rem;
	max-width: 21rem;
}

.size-button {
	display: grid;
	flex: 0 0 auto;
	place-items: center;
	width: 2.15rem;
	height: 2.15rem;
	border-radius: 50%;
	font: inherit;
	font-size: .75rem;
	font-weight: 700;
	letter-spacing: -.02em;
	color: var(--color-size-text);
	background: var(--color-size);
	transition: color .15s ease-in-out, background-color .15s ease-in-out, scale .15s ease-in-out;
}

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

.size-button.is-selected {
	color: var(--color-on-button-primary);
	background: var(--color-button-primary);
	scale: 1.06;
}

/* On a person's details the sizes go on to a second line when a narrow column has no
   room for all seven (Sep 29) */
:is(#profile-form, #person-form, #formpage-form) .size-row {
	flex-wrap: wrap;
	max-width: none;
	justify-content: flex-start;
	gap: .25rem;
}

:is(#profile-form, #person-form, #formpage-form) .size-button {
	width: 2rem;
	height: 2rem;
	font-size: .7rem;
	letter-spacing: -.04em;
}

/* Read-only values: label left, value right */
.facts {
	margin: 0;
	font-size: .9375rem;
}

.facts > div {
	display: flex;
	justify-content: space-between;
	gap: 1rem;
	padding: .5rem 0;
	border-top: 1px solid var(--color-tile-separator);
}

.facts > div:first-child {
	padding-top: 0;
	border-top: 0;
}

.facts > div:last-child {
	padding-bottom: 0;
}

.facts dt {
	flex-shrink: 0;
	color: var(--color-text-secondary);
}

.facts dd {
	min-width: 0;
	margin: 0;
	font-weight: 500;
	text-align: right;
	overflow-wrap: break-word;
}

/* Switch rows (permissions): name + explanation, switch on the right */
.toggle-row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: .75rem;
	padding: .6rem 0;
	border-top: 1px solid var(--color-tile-separator);
	font-size: .9375rem;
	cursor: pointer;
}

.toggle-row:first-child {
	padding-top: 0;
	border-top: 0;
}

.toggle-row:last-child {
	padding-bottom: 0;
}

.toggle-row small {
	display: block;
	margin-top: .1rem;
	font-size: .8125rem;
	line-height: 1.15rem;
	color: var(--color-text-secondary);
}

.toggle-row .switch {
	width: 3.2rem;
	height: 1.5rem;
}

.toggle-row .switch::before {
	top: .1875rem;
	left: .1875rem;
	width: 1.7rem;
	height: 1.125rem;
	border-radius: .5625rem;
}

.toggle-row .switch:checked::before {
	translate: 1.125rem 0;
}

.switch:disabled {
	opacity: .5;
	cursor: default;
}

.toggle-row:has(.switch:disabled) {
	cursor: default;
}

/* ---------- Profile card (photo + name) ---------- */
.profile-card {
	display: flex;
	flex-direction: column;
	align-items: center;
	padding-block: 1.25rem;
	text-align: center;
}

.profile-name {
	margin: .7rem 0 .15rem;
	font-size: 1.25rem;
	font-weight: 700;
	line-height: 1.25;
	letter-spacing: -.015em;
}

.profile-meta {
	margin: .1rem 0 0;
	font-size: .875rem;
	font-variant-numeric: tabular-nums;
	color: var(--color-text-secondary);
	overflow-wrap: anywhere;
}

.avatar img {
	display: block;
	width: 100%;
	height: 100%;
	border-radius: 50%;
	object-fit: cover;
}

.avatar-medium {
	width: 2.5rem;
	height: 2.5rem;
	font-size: .8125rem;
	color: var(--color-avatar-text);
	background: var(--color-avatar);
}

.avatar-large {
	width: 5.5rem;
	height: 5.5rem;
	font-size: 1.7rem;
	color: var(--color-avatar-text);
	background: var(--color-avatar);
}

/* Photo on a profile card. Two separate taps:
   the photo itself shows it full size, the camera badge opens the photo menu. */
.avatar-wrap {
	position: relative;
	display: inline-block;
}

.avatar-button {
	display: block;
	border-radius: 50%;
}

.avatar-wrap.busy .avatar-button,
.avatar-button:disabled {
	cursor: progress;
	opacity: .6;
}

/* While a photo is being saved the badge can't be tapped again */
.avatar-wrap.busy .avatar-badge {
	pointer-events: none;
	opacity: .6;
}

/* The camera badge is its own button (it used to sit inside the photo button) */
.avatar-badge {
	position: absolute;
	right: -.1rem;
	bottom: -.1rem;
	display: grid;
	place-items: center;
	width: 1.9rem;
	height: 1.9rem;
	border-radius: 50%;
	color: var(--color-on-button-primary);
	background: var(--color-button-primary);
	transition: background-color .2s ease-in-out;
}

.avatar-badge:hover {
	background: var(--color-button-primary-hover);
}

/* Bin on the other corner: takes the photo away (asks first). Only there while
   there is a photo to remove. */
.avatar-badge-remove {
	right: auto;
	left: -.1rem;
	color: var(--color-on-badge-remove);
	background: var(--color-badge-remove);
}

.avatar-badge-remove:hover {
	background: var(--color-badge-remove-hover);
}

.avatar-badge-remove svg {
	width: 1.05rem;
	height: 1.05rem;
	stroke-width: 1.8;
}

.avatar-badge svg {
	width: 1rem;
	height: 1rem;
	stroke-width: 2;
}

/* ---------- Photo menu ---------- */
/* Same look as the order menu on the Users page, instead of the picker sheet the
   phone would show by itself. Hangs under the camera badge, centered on the photo. */
.dropdown-menu.avatar-menu {
	top: calc(100% + .5rem);
	left: 50%;
	right: auto;
	transform: translateX(-50%);
	min-width: 11rem;
	text-align: left;
}

.dropdown-menu.avatar-menu.open {
	opacity: 1;
	scale: 1;
	translate: 0 0;
	visibility: visible;
	transition: opacity .15s ease-in-out, scale .15s ease-in-out, translate .15s ease-in-out, visibility 0s;
}

/* The rows themselves look like every other menu row (.dropdown-menu .menu-option).
   A row here is a <label> around a hidden file input: tapping the label is a real tap
   on the input itself, which phones handle far better than a click() from script. */
.avatar-menu .menu-option {
	position: relative;
	cursor: pointer;
}

.avatar-menu .menu-option:has(input:focus-visible) {
	background: var(--color-menu-hover);
}

.avatar-menu .menu-option svg {
	stroke-width: 1.9;
}

/* The file input stays in the page (not display:none) so the tap reaches it */
.avatar-menu .menu-option input[type="file"] {
	position: absolute;
	width: 1px;
	height: 1px;
	opacity: 0;
	pointer-events: none;
}

/* ---------- Photo full size ---------- */
/* Tapping a profile photo shows it in the middle of the screen. */
.photo-viewer {
	max-width: none;
	max-height: none;
	width: 100%;
	height: 100%;
	margin: 0;
	padding: 0;
	border: 0;
	background: transparent;
	overflow: hidden;
	opacity: 0;
	/* Everything that positions the photo lives here and not under [open]: on closing,
	   the [open] rules stop applying at once while the pop-up is still fading out, so a
	   centering set there would drop the photo into the corner first. */
	place-items: center;
	transition: opacity .2s ease-in-out, overlay .2s allow-discrete, display .2s allow-discrete;
}

.photo-viewer[open] {
	display: grid;
	opacity: 1;
}

@starting-style {
	.photo-viewer[open] {
		opacity: 0;
	}
}

.photo-viewer::backdrop {
	background: #00000000;
	-webkit-backdrop-filter: blur(0) saturate(1);
	backdrop-filter: blur(0) saturate(1);
	transition: background-color .2s ease-in-out, backdrop-filter .2s ease-in-out,
		overlay .2s allow-discrete, display .2s allow-discrete;
}

.photo-viewer[open]::backdrop {
	background: var(--color-photo-backdrop);
	-webkit-backdrop-filter: blur(14px) saturate(.35);
	backdrop-filter: blur(14px) saturate(.35);
}

@starting-style {
	.photo-viewer[open]::backdrop {
		background: #00000000;
		-webkit-backdrop-filter: blur(0) saturate(1);
		backdrop-filter: blur(0) saturate(1);
	}
}

.photo-viewer img {
	display: block;
	max-width: min(calc(100vw - 3rem), 34rem);
	max-height: calc(100dvh - 4rem);
	border-radius: .5rem;
	box-shadow: 0 1.5rem 4rem var(--color-photo-shadow);
	object-fit: contain;
	scale: .96;
	transition: scale .2s ease-in-out;
}

.photo-viewer[open] img {
	scale: 1;
}

@starting-style {
	.photo-viewer[open] img {
		scale: .96;
	}
}

/* Round close button, top right of the screen */
.photo-viewer-close {
	position: fixed;
	top: max(1rem, env(safe-area-inset-top));
	right: 1rem;
	display: grid;
	place-items: center;
	width: 2.25rem;
	height: 2.25rem;
	border-radius: 50%;
	color: var(--color-label);
	background: var(--color-close);
	transition: background-color .15s ease-in-out;
}

.photo-viewer-close:hover {
	background: var(--color-close-hover);
}

.photo-viewer-close svg {
	width: 1.1rem;
	height: 1.1rem;
	stroke-width: 2.2;
}

.link-button {
	margin-top: .6rem;
	font-size: .875rem;
	color: var(--color-link);
}

.link-button:hover {
	text-decoration: underline;
}

.link-button-destructive {
	color: var(--color-destructive);
}

/* ---------- Toolbar above a list (search + filter) ---------- */
.toolbar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: .75rem;
	margin-bottom: 1rem;
}

.search {
	display: flex;
	flex: 1 1 14rem;
	align-items: center;
	gap: .5rem;
	max-width: 22rem;
	min-height: 2.5rem;
	padding: 0 .9rem;
	border-radius: 1.25rem;
	color: var(--color-text-secondary);
	background: var(--color-filter-track);
}

.search svg {
	flex-shrink: 0;
	width: 1.1rem;
	height: 1.1rem;
}

.search input {
	flex: 1;
	min-width: 0;
	margin: 0;
	padding: 0;
	border: 0;
	outline: 0;
	font: inherit;
	font-size: .9375rem;
	color: var(--color-text);
	background: transparent;
}

.search input::placeholder {
	color: var(--color-placeholder);
}

.toolbar .filter {
	flex: 0 1 auto;
	margin: 0;
}

/* ---------- Compact toolbar (Users) ---------- */
/* Same controls, roughly a third less height, so more of the list fits on a phone. */
.toolbar-compact {
	gap: .4rem;
	margin-bottom: .7rem;
}

.toolbar-compact .search {
	flex: 1 1 6rem;
	min-width: 5rem;
	max-width: 18rem;
	min-height: 2rem;
	gap: .4rem;
	padding: 0 .7rem;
	border-radius: 1rem;
}

/* A long order name is cut off rather than pushing the row onto a second line */
.toolbar-compact .dropdown-value {
	max-width: 7.5rem;
}

/* Phones: search, order and the functions button share the first line and the
   filter takes the second, instead of every control claiming a line of its own */
/* Phones: two rows instead of four. A grid rather than wrapping flex, so the break
   always lands in the same place.
     row 1   search .................... ⋯
     row 2   order ............... filter  */
@media (max-width: 34rem) {
	/* The two rows want different splits (row 1 is mostly search, row 2 is mostly
	   filter), which shared grid columns can't give. So: a wrapping flex row with an
	   empty full-width item forced between them to break the line where we want. */
	.toolbar-compact::before {
		content: "";
		order: 1;
		flex: 0 0 100%;
		height: 0;
		/* takes back the row gap this extra line would otherwise add */
		margin-block: -.2rem;
	}

	/* flex-basis 0, not auto: an input asks for about 20 characters of width, which is
	   just wide enough to shove the order pill onto a line of its own. This lets the
	   search start small and grow into whatever the order pill leaves over. */
	.toolbar-compact .search {
		flex: 1 1 0;
		min-width: 6rem;
		max-width: none;
	}

	/* Keeps its own width; the search takes what is left of the first row */
	.toolbar-compact #user-sort,
	.toolbar-compact #vehicle-sort {
		order: 0;
		flex: 0 0 auto;
	}

	.toolbar-compact .dropdown-value {
		max-width: 6.5rem;
	}

	/* Second row, on its own */
	.toolbar-compact .filter {
		order: 2;
		flex: 1 1 100%;
		max-width: none;
	}

	/* Assignments and Archive have only a search and a filter: those two share one
	   line — search on the left, taking what the filter leaves over. */
	.toolbar-compact:not(:has(.dropdown))::before {
		display: none;
	}

	.toolbar-compact:not(:has(.dropdown)) {
		flex-wrap: nowrap;
	}

	.toolbar-compact:not(:has(.dropdown)) .search {
		min-width: 4.5rem;
	}

	/* Each tab as wide as what it shows, rather than three equal thirds: the search
	   gets the room the icon-only tabs don't need */
	.toolbar-compact:not(:has(.dropdown)) .filter {
		order: 0;
		flex: 0 0 auto;
		grid-auto-columns: auto;
	}

	.toolbar-compact:not(:has(.dropdown)) .filter label > span {
		padding-inline: .55rem;
	}

	/* The order pill ends at the right edge on a phone, so its menu hangs to the left
	   of that edge instead of past it */
	.toolbar-compact #user-sort .dropdown-menu,
	.toolbar-compact #vehicle-sort .dropdown-menu {
		left: auto;
		right: 0;
	}

	/* Only the filter you are on says what it is; the rest are their icon and count,
	   which is what makes both controls fit on one row. The words stay in the page
	   for screen readers. */
	.toolbar-compact .filter-icon,
	.filter-compact .filter-icon {
		display: block;
	}

	.toolbar-compact .filter input:not(:checked) + span .filter-label,
	.filter-compact input:not(:checked) + span .filter-label {
		position: absolute;
		width: 1px;
		height: 1px;
		overflow: hidden;
		clip-path: inset(50%);
		white-space: nowrap;
	}
}

.toolbar-compact .search svg {
	width: .95rem;
	height: .95rem;
}

.toolbar-compact .search input,
.toolbar-compact .filter label > span,
.filter-compact label > span,
.toolbar-compact .dropdown-button {
	font-size: .8125rem;
}

.toolbar-compact .filter,
.filter-compact {
	gap: .1rem;
	padding: .125rem;
	border-radius: 1rem;
}

.toolbar-compact .filter label > span,
.filter-compact label > span {
	gap: .25rem;
	min-height: 1.75rem;
	padding: 0 .5rem;
	border-radius: .875rem;
}

.toolbar-compact .filter-count,
.filter-compact .filter-count {
	font-size: .6875rem;
}

/* Drawn only on phones (see the media query above); desktop keeps the words */
.filter-icon {
	display: none;
	flex-shrink: 0;
	width: 1.05rem;
	height: 1.05rem;
}

.toolbar-compact .sort-pill {
	min-height: 2rem;
	padding-left: .2rem;
	border-radius: 1rem;
}

.toolbar-compact .sort-direction {
	width: 1.6rem;
	height: 1.6rem;
}

.toolbar-compact .sort-direction svg {
	width: .9rem;
	height: .9rem;
}

/* Only the order pill's button is a half-pill (the round reverse button is its left
   half). The functions button is on its own and stays a full circle. */
.toolbar-compact .sort-pill .dropdown-button {
	gap: .3rem;
	padding: 0 .6rem 0 .4rem;
	border-radius: 0 1rem 1rem 0;
}

.toolbar-compact .dropdown-arrow {
	width: .85rem;
	height: .85rem;
}

/* Round button that opens the page's functions menu (⋯).
   Flex rather than grid with place-items: this button also carries .dropdown-button,
   whose display: flex sits further down the file and would win, which left the dots
   against the left edge. Both centering properties are set here so the icon stays in
   the middle whichever of the two rules ends up applying. */
.icon-pill {
	display: flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	width: 2rem;
	height: 2rem;
	padding: 0;
	border-radius: 50%;
	color: var(--color-text);
	background: var(--color-filter-track);
	transition: background-color .15s ease-in-out;
}

/* In a panel header it sits next to New and matches the round full-screen button */
/* Smaller than the buttons beside it on purpose: it is the quietest control in the
   header. The header is a centred flex row, so it lines up in the middle by itself. */
.panel-head .icon-pill {
	width: 2rem;
	height: 2rem;
	color: var(--color-panel-button-icon);
	background: var(--color-panel-button);
}

.panel-head .icon-pill:hover,
.panel-head .dropdown.open .icon-pill {
	background: var(--color-panel-button-hover);
}

.panel-head .icon-pill svg {
	width: 1.15rem;
	height: 1.15rem;
}

.icon-pill:hover,
.dropdown.open .icon-pill {
	background: var(--color-button-secondary-hover);
}

.icon-pill svg {
	width: 1.15rem;
	height: 1.15rem;
	fill: currentColor;
	stroke: none;
}

/* The functions menu is the last thing in the row, so it opens to the left */
/* Two classes, so this beats the left: 0 of the plain .dropdown-menu further down */
.dropdown-menu.dropdown-menu-end {
	left: auto;
	right: 0;
}

/* Rows with an icon in front of the label (the functions menu) */
/* No width here: the menu is a grid, and a row asking for 100% would make the menu
   measure itself against the row instead of the row against its text, which collapses
   the whole menu to the width of the button that opened it. */
.dropdown-menu .menu-option {
	display: flex;
	align-items: center;
	gap: .55rem;
	padding: .5rem .75rem;
	border-radius: .7rem;
	font: inherit;
	font-size: .9375rem;
	white-space: nowrap;
	text-align: left;
	color: var(--color-text);
	transition: background-color .12s ease-in-out;
}

.dropdown-menu .menu-option:hover,
.dropdown-menu .menu-option:focus-visible {
	outline: none;
	background: var(--color-menu-hover);
}

.dropdown-menu .menu-option svg {
	flex-shrink: 0;
	width: 1.05rem;
	height: 1.05rem;
}

/* Filter options take the room their label needs */
.filter {
	max-width: 30rem;
}

[data-page="users"] .filter {
	grid-auto-columns: auto;
}

/* ---------- Dropdown menu (order picker) ---------- */
/* A pill like the search field; the whole pill opens a small rounded menu below it */
.dropdown {
	position: relative;
	flex: 0 0 auto;
}

/* The pill holds the round reverse button and the button that opens the menu */
.sort-pill {
	display: flex;
	align-items: center;
	min-height: 2.5rem;
	padding-left: .3rem;
	border-radius: 1.25rem;
	background: var(--color-filter-track);
	transition: background-color .15s ease-in-out;
}

.sort-pill:has(.dropdown-button:hover),
.dropdown.open .sort-pill {
	background: var(--color-button-secondary-hover);
}

/* Round, own background: flips the order. Mirrored arrows = reversed. */
.sort-direction {
	display: grid;
	flex-shrink: 0;
	place-items: center;
	width: 1.9rem;
	height: 1.9rem;
	border-radius: 50%;
	color: var(--color-text);
	background: var(--color-sort-direction);
	transition: background-color .15s ease-in-out;
}

.sort-direction:hover {
	background: var(--color-sort-direction-hover);
}

.sort-direction svg {
	width: 1.05rem;
	height: 1.05rem;
	stroke-width: 2.1;
	transition: scale .2s ease-in-out;
}

.sort-direction[aria-pressed="true"] svg {
	scale: -1 1;
}

.dropdown-button {
	display: flex;
	align-items: center;
	align-self: stretch;
	gap: .45rem;
	font-size: .9375rem;
	font-weight: 500;
	color: var(--color-text);
}

/* Inside the order pill the button is the right half, so only that side is rounded.
   A dropdown button that stands on its own (the functions ⋯) keeps its own shape. */
.sort-pill .dropdown-button {
	padding: 0 .8rem 0 .55rem;
	border-radius: 0 1.25rem 1.25rem 0;
}

/* While the width animates, the text is clipped instead of pushing the arrow out */
.dropdown-value {
	min-width: 0;
	overflow: hidden;
	white-space: nowrap;
}

.dropdown-arrow {
	flex-shrink: 0;
	width: 1.1rem;
	height: 1.1rem;
	color: var(--color-text-secondary);
}

.dropdown-arrow {
	width: 1rem;
	height: 1rem;
	stroke-width: 2.2;
	transition: rotate .2s ease-in-out;
}

.dropdown.open .dropdown-arrow {
	rotate: 180deg;
}

.dropdown-menu {
	position: absolute;
	top: calc(100% + .35rem);
	left: 0;
	z-index: 20;
	display: grid;
	min-width: 100%;
	padding: .35rem;
	border-radius: 1rem;
	background: var(--color-menu);
	box-shadow: 0 .5rem 1.75rem var(--color-menu-shadow);
	opacity: 0;
	scale: .97;
	translate: 0 -.25rem;
	visibility: hidden;
	transition: opacity .15s ease-in-out, scale .15s ease-in-out, translate .15s ease-in-out, visibility .15s;
}

.dropdown.open .dropdown-menu {
	opacity: 1;
	scale: 1;
	translate: 0 0;
	visibility: visible;
	/* Visible right away when opening (so the current choice can get keyboard focus) */
	transition: opacity .15s ease-in-out, scale .15s ease-in-out, translate .15s ease-in-out, visibility 0s;
}

.dropdown-menu [role="option"] {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding: .55rem .8rem;
	border-radius: .7rem;
	font-size: .9375rem;
	white-space: nowrap;
	text-align: left;
	color: var(--color-text);
	transition: background-color .12s ease-in-out;
}

.dropdown-menu [role="option"]:hover,
.dropdown-menu [role="option"]:focus {
	outline: none;
	background: var(--color-menu-hover);
}

/* The current choice: bold with a check mark */
.dropdown-menu [aria-selected="true"] {
	font-weight: 600;
}

.dropdown-menu [aria-selected="true"]::after {
	content: "";
	flex-shrink: 0;
	width: .3rem;
	height: .6rem;
	/* The tick is a rotated box, so it paints wider than it measures. The extra right
	   margin keeps the corner clear of the menu's edge. */
	margin: 0 .35rem .15rem 0;
	border-right: 2px solid var(--color-accent);
	border-bottom: 2px solid var(--color-accent);
	rotate: 45deg;
}

/* Text for screen readers only */
.visually-hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

/* ---------- People list (Users page) ---------- */
.people {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
	gap: .35rem;
}

.people > .empty {
	grid-column: 1 / -1;
	margin: 1rem 0;
}

.person-row {
	position: relative;
	display: flex;
	align-items: center;
	gap: .6rem;
	min-width: 0;
	padding: .4rem .6rem;
	border-radius: .8rem;
	corner-shape: squircle;
	background: var(--color-tile-item);
	transition: background-color .15s ease-in-out;
}

.person-row:hover {
	background: var(--color-tile-item-hover);
}

.person-row-main {
	flex: 1;
	min-width: 0;
}

.person-row-name,
.person-row-sub {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.person-row-name {
	margin: 0;
	font-size: .875rem;
	font-weight: 600;
	line-height: 1.2;
}

.person-row-sub {
	margin: 0;
	font-size: .75rem;
	line-height: 1.2;
	font-variant-numeric: tabular-nums;
	color: var(--color-text-secondary);
}

.person-row-chips {
	display: flex;
	flex-wrap: wrap;
	gap: .2rem;
	margin-top: .2rem;
}

.person-row-chips:empty {
	display: none;
}

.person-row .chip {
	padding: 0 .4rem;
	font-size: .625rem;
	line-height: .95rem;
}

.you {
	font-weight: 400;
	color: var(--color-text-secondary);
}

/* "This is you" after your own name (youMark in script.js, Oct 20; it said "(jij)"):
   a soft green circle with a lighter green star, built like the info "i" */
/* Whole pixels on purpose (18 and 14px, Oct 20): with 16.8 and 14.08px the room around
   the star had to be rounded, and at 100% zoom it sat a pixel low */
.you-mark {
	display: inline-grid;
	place-items: center;
	width: 1.125rem;
	height: 1.125rem;
	margin-left: .3rem;
	border-radius: 50%;
	vertical-align: -.2em;
	color: var(--color-on-you);
	background: var(--color-you);
}

.you-mark svg {
	display: block;
	width: .875rem;
	height: .875rem;
	fill: currentColor;
	stroke: currentColor;
	stroke-width: 1.5;
	stroke-linejoin: round;
}

/* Person chips reuse the status chip colors */
.chip-person-sick { color: var(--color-on-status-denied); background: var(--color-status-denied); }
.chip-person-vacation { color: var(--color-on-status-request); background: var(--color-status-request); }
.chip-person-inactive,
.chip-person-nologin { color: var(--color-on-status-completed); background: var(--color-status-completed); }
/* A login code waiting to be used (Oct 21): the blue-grey of "waiting", red once it ran out */
.chip-person-code { color: var(--color-on-status-submitted); background: var(--color-status-submitted); }
.chip-person-code-expired { color: var(--color-on-status-denied); background: var(--color-status-denied); }
.chip-person-freelancer { color: var(--color-on-status-accepted); background: var(--color-status-accepted); }
.chip-person-permissions { color: var(--color-on-status-in-progress); background: var(--color-status-in-progress); }

/* ---------- Wide sheet (edit a person) ---------- */
/* Same pop-up as the others, but white with tiles in up to 2 columns */
.sheet-wide {
	width: min(calc(100% - 2rem), 48rem);
	background: var(--color-panel);
}

/* Same space under the last tile as at the sides, when scrolled to the end */
.sheet-wide .settings-inner {
	padding-bottom: 1rem;
}

.sheet-wide {
	--sheet-bg: var(--color-panel);
}

.sheet-wide .settings-head {
	grid-template-columns: 6rem 1fr 6rem;
	margin-bottom: .25rem;
}

.sheet-wide .settings-head .button {
	grid-column: 3;
	grid-row: 1;
	justify-self: end;
}

.sheet-wide .tiles {
	--tile-cols: 2;
}

/* ---------- Small round icon button (delete) ---------- */
.icon-button {
	flex-shrink: 0;
	display: grid;
	place-items: center;
	width: 2.25rem;
	height: 2.25rem;
	border-radius: 50%;
	transition: background-color .2s ease-in-out;
}

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

.icon-button svg {
	width: 1.2rem;
	height: 1.2rem;
}

.icon-button-destructive {
	color: var(--color-destructive);
}

.row-sub {
	display: block;
	margin-top: .1rem;
	font-size: .8125rem;
	line-height: 1.1rem;
	color: var(--color-label-secondary);
}

/* Job types: the add button sits inside the input row */
#job-type-form .field-row {
	padding-right: .5rem;
}

.group-note {
	margin: .5rem 1rem 0;
	font-size: .8125rem;
	line-height: 1.15rem;
	color: var(--color-label-secondary);
}

/* ---------- Vehicles page ---------- */
/* A card reads like a playing card: taller than it is wide, with a photo and a name
   at the top, the facts under it in plain text, and a month of calendar at the
   bottom. One chip only — what the vehicle is doing right now. */
.vehicles {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
	gap: .6rem;
}

.vehicles > .empty {
	grid-column: 1 / -1;
	margin: 1rem 0;
}

.vehicle-card {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: .7rem;
	min-width: 0;
	padding: .7rem .75rem .8rem;
	border-radius: 1rem;
	corner-shape: squircle;
	background: var(--color-tile-item);
	transition: background-color .15s ease-in-out;
}

.vehicle-card:hover {
	background: var(--color-tile-item-hover);
}

/* The photo is wide enough to carry the card, and the name, the chip and the values
   underneath them all start at the same left edge: --photo-column. */
.vehicle-card {
	--photo-size: 4.5rem;
	--photo-gap: .6rem;
	--photo-column: calc(var(--photo-size) + var(--photo-gap));
}

.vehicle-card-top {
	display: flex;
	gap: var(--photo-gap);
	align-items: center;
	min-width: 0;
}

.vehicle-card-main {
	flex: 1;
	min-width: 0;
}

.vehicle-card-name {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.vehicle-card-name {
	margin: 0;
	font-size: .9375rem;
	font-weight: 650;
	line-height: 1.25;
}

/* A licence plate is read as a plate: spaced out a little, never wrapped */
.vehicle-plate {
	margin: .1rem 0 0;
	font-size: .75rem;
	font-weight: 600;
	letter-spacing: .04em;
	font-variant-numeric: tabular-nums;
	text-transform: uppercase;
	color: var(--color-text-secondary);
}

.vehicle-card-chips {
	display: flex;
	flex-wrap: wrap;
	gap: .2rem;
	margin-top: .3rem;
}

/* Smaller and wider than a chip elsewhere, with tighter corners */
.vehicle-card .chip {
	padding: 0 .6rem;
	border-radius: .35rem;
	corner-shape: squircle;
	font-size: .5625rem;
	letter-spacing: .01em;
	line-height: .9rem;
}

/* Facts in plain text: the label quiet on the left, the value in bold on the right */
.vehicle-facts {
	margin: 0;
	font-size: .75rem;
	line-height: 1.1rem;
}

.vehicle-facts > div {
	display: grid;
	grid-template-columns: var(--photo-column) minmax(0, 1fr);
	align-items: baseline;
	padding: .04rem 0;
}

.vehicle-facts dt {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	color: var(--color-text-secondary);
}

.vehicle-facts dd {
	min-width: 0;
	margin: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-weight: 650;
}

/* A licence plate is read as a plate wherever it turns up */
.vehicle-facts dd.is-plate {
	letter-spacing: .03em;
	font-variant-numeric: tabular-nums;
	text-transform: uppercase;
}

.vehicle-facts dd.is-expired,
.inspection-date-label.is-expired { color: var(--color-expired); }
.vehicle-facts dd.is-soon,
.inspection-date-label.is-soon { color: var(--color-soon); }

/* An inspection is one line: APK · Geldig tot 12 mei 2027, the state and the date as
   one sentence with a single space between them (Sep 30: no column of their own any
   more). The date is quieter than the state, and only takes a colour of its own when
   it is nearly there (amber) or has run out (red). A line too long for the card ends
   in an ellipsis, like the other facts. */

.fact-until {
	font-weight: 500;
	color: var(--color-text-secondary);
}

.fact-until.is-expired { color: var(--color-expired); }
.fact-until.is-soon { color: var(--color-soon); }

/* The photo, or the kind of vehicle as an icon while there is none */
.vehicle-photo {
	flex-shrink: 0;
	display: grid;
	place-items: center;
	width: var(--photo-size, 3.5rem);
	height: var(--photo-size, 3.5rem);
	overflow: hidden;
	border-radius: .7rem;
	corner-shape: squircle;
	color: var(--color-vehicle-photo-icon);
	background: var(--color-vehicle-photo);
}

.vehicle-photo img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.vehicle-photo svg {
	width: 2.2rem;
	height: 2.2rem;
}

/* ---------- Vehicle calendar ---------- */
/* Two flat blocks that belong together: a narrow column of week numbers and the grid
   of days, with a small gap and tighter corners where they meet. One cell per day
   with the date in it. Whole days only: half days and hours would never be kept up to
   date, and everything runs late anyway. */
.agenda {
	--day-height: 1.5rem;             /* a card's calendar (was 1.35rem) */
	--head-height: .9rem;
	--agenda-gap: .15rem;
	display: flex;
	gap: .2rem;
	align-items: stretch;
}

/* Every calendar you tap in (vehicle pop-up, new assignment) is the same height:
   easy to hit with a thumb (Sep 25: taller, was 1.7rem / 2rem) */
.agenda-interactive {
	--day-height: 2.25rem;
	--head-height: 1rem;
}

.agenda-weeks,
.agenda-grid {
	display: grid;
	gap: var(--agenda-gap);
	grid-auto-rows: var(--day-height);
	padding: .35rem;
	background: var(--color-agenda);
}

/* Big radius on the outside, small where the two blocks meet */
.agenda-weeks {
	flex: 0 0 auto;
	justify-items: center;
	padding-inline: .3rem;
	border-radius: .6rem .2rem .2rem .6rem;
}

.agenda-grid {
	flex: 1;
	min-width: 0;
	border-radius: .2rem .6rem .6rem .2rem;
}

/* The weekday letters, and the empty box in front of them, are a shorter row */
.agenda-weeks > .agenda-spacer,
.agenda-grid > .agenda-head {
	height: var(--head-height);
}

.agenda-weeks > .agenda-spacer:first-child,
.agenda-grid > .agenda-head:first-child {
	grid-row: 1;
}

.agenda-week-number {
	display: grid;
	place-items: center;
	font-size: .5625rem;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	color: var(--color-placeholder);
}

.agenda-days {
	display: grid;
	grid-template-columns: repeat(7, 1fr);
	gap: var(--agenda-gap);
	min-width: 0;
}

.agenda-head span {
	display: grid;
	place-items: center;
	font-size: .5625rem;
	font-weight: 700;
	text-transform: uppercase;
	color: var(--color-placeholder);
}

.day-cell {
	display: grid;
	place-items: center;
	width: 100%;
	height: 100%;
	padding: 0;
	border: 0;
	border-radius: .35rem;
	corner-shape: squircle;
	font-size: .625rem;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	line-height: 1;
	color: var(--color-text-secondary);
	background: transparent;
}

/* Only a day that is taken is filled in, so the block reads as a calendar rather
   than as a grid of buttons */
.day-cell.is-weekend {
	color: var(--color-day-weekend);
}

.day-cell.is-past {
	opacity: .55;
}

.day-cell.is-booked {
	color: var(--color-on-day-booked);
	background: var(--color-day-booked);
}

/* A taken day that has passed: an almost grey fill instead of the brand colour, not
   just the same fill turned down (Sep 25). Every calendar with the brand fill. */
.day-cell.is-past.is-booked {
	opacity: 1;
	color: var(--color-on-day-past);
	background: var(--color-day-past);
}

/* Today is the darkest of the three, whether it is free or taken */
.day-cell.is-today {
	color: var(--color-on-day-today);
	background: var(--color-day-today);
	opacity: 1;
}

/* The calendar in the pop-up is the one you can tap, so its days are bigger.
   pan-y leaves vertical scrolling to the browser and lets a sideways drag pick a
   period; without it a drag on a phone just scrolls the sheet. */
.agenda-interactive .day-cell {
	font-size: .75rem;
	cursor: pointer;
	touch-action: pan-y;
	transition: background-color .15s ease-in-out, color .15s ease-in-out;
}

/* While a period is being dragged out */
.agenda-interactive .day-cell.is-range {
	color: var(--color-on-day-booked);
	background: var(--color-day-booked);
}

.agenda-interactive .day-cell:hover {
	color: var(--color-on-day-booked);
	background: var(--color-day-booked);
}

/* The calendar sits at the bottom of every card, so a card with fewer facts still
   lines its calendar up with the others in the row */
.card-agenda {
	margin-top: auto;
}

/* Month and the two arrows above a card's calendar. It sits above the invisible
   layer that makes the whole card tappable, so the arrows stay clickable. */
.card-agenda-head {
	position: relative;
	z-index: 1;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: .5rem;
	margin-bottom: .25rem;
	padding: 0 .1rem;
}

.card-agenda-month {
	font-size: .6875rem;
	font-weight: 600;
	color: var(--color-text-secondary);
}

.card-agenda-nav {
	display: flex;
	gap: .1rem;
}

.card-arrow {
	display: grid;
	place-items: center;
	width: 1.25rem;
	height: 1.25rem;
	border-radius: .375rem;
	color: var(--color-text-secondary);
	transition: background-color .15s ease-in-out, color .15s ease-in-out;
}

.card-arrow:hover {
	color: var(--color-text);
	background: var(--color-agenda);
}

.card-arrow svg {
	width: .9rem;
	height: .9rem;
	stroke-width: 2.2;
}

.agenda-nav {
	display: flex;
	flex: 0 0 auto;
	gap: .25rem;
}

.agenda-nav .icon-pill {
	width: 1.75rem;
	height: 1.75rem;
	font-size: .75rem;
	font-weight: 600;
}

.agenda-nav .icon-pill:hover {
	background: var(--color-filter-active);
}

.agenda-nav .icon-pill svg {
	width: 1.1rem;
	height: 1.1rem;
}

/* Month names are written the way the language writes them (Dutch keeps them
   lower case), so nothing is capitalised here. */
.agenda-month {
	margin: -.25rem 0 .5rem;
	font-size: .8125rem;
	font-weight: 500;
	color: var(--color-text-secondary);
}

#vehicle-agenda .button {
	margin-top: .75rem;
}

/* ---------- Vehicle pop-up ---------- */
/* Photo tile at the top: the same badges as a profile card, on a wide box instead
   of a circle. */
.vehicle-hero {
	text-align: center;
}

.vehicle-photo-wrap {
	position: relative;
	display: inline-block;
	margin-bottom: .5rem;
}

.vehicle-photo-button {
	display: block;
	border-radius: 1rem;
}

.vehicle-photo-large {
	width: 11rem;
	max-width: 100%;
	height: 7.5rem;
	border-radius: 1rem;
}

.vehicle-photo-large svg {
	width: 2.6rem;
	height: 2.6rem;
}

.vehicle-hero .profile-name {
	margin-bottom: 0;
}

.vehicle-hero .vehicle-plate {
	margin-top: .15rem;
}

/* Make and model sit under the picture, as drawn in the design */
.vehicle-hero-model {
	margin: .25rem 0 0;
	font-size: .875rem;
	color: var(--color-text-secondary);
}

/* The Active switch is a panel of its own at the very end */
.tile-active .toggle-row {
	padding: 0;
}

/* ---------- Inspections (APK / BMWT / TCVO) ---------- */
/* Kept tight: the name and its Geldigheid dropdown on one line, the date under it.
   The date normally decides what the dropdown says. */
.tile-inspections .inspection + .inspection {
	margin-top: .55rem;
	padding-top: .55rem;
	border-top: 1px solid var(--color-tile-separator);
}

/* Everything on the left, in one column: the name with its Geldig dropdown under
   it, then "Verloopt op" with the date under it. Always stacked, so the three
   inspections look the same whatever month they expire in. */
.inspection-row {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: .5rem;
}

.inspection-part {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: .3rem;
	min-width: 0;
}

.inspection-part-date {
	flex: 0 1 auto;
}

.inspection-name {
	font-size: .9375rem;
	font-weight: 650;
	line-height: 1.2;
}

.tile-inspections {
	--inspection-control: 8.2rem;
}

.inspection-part .field-dropdown {
	flex: 0 0 auto;
	width: var(--inspection-control);
}

.inspection-date-label {
	font-size: .8125rem;
	font-weight: 500;
	line-height: 1.45;
	color: var(--color-text-secondary);
}

.inspection-part .date-pill {
	max-width: 100%;
}

.inspection-hint {
	margin: .3rem 0 0;
	font-size: .75rem;
	font-weight: 500;
	color: var(--color-soon);
}

/* Vehicle status chips: free green, in use blue, inactive yellow */
.chip-vehicle-available { color: var(--color-on-status-in-progress); background: var(--color-status-in-progress); }
.chip-vehicle-in_use { color: var(--color-on-status-accepted); background: var(--color-status-accepted); }
.chip-vehicle-inactive { color: var(--color-on-status-request); background: var(--color-status-request); }

/* ---------- Garage log ---------- */
/* An archive: what happened and when. Lines are written down, not ticked off. */
.log-list {
	display: grid;
	gap: .3rem;
}

.log-entry {
	display: flex;
	align-items: flex-start;
	gap: .5rem;
	padding: .45rem .5rem;
	border-radius: .7rem;
	corner-shape: squircle;
	background: var(--color-tile-item);
}

.log-main {
	flex: 1;
	min-width: 0;
}

.log-text {
	margin: 0;
	font-size: .875rem;
	line-height: 1.2rem;
	overflow-wrap: anywhere;
}

.log-meta {
	margin: .1rem 0 0;
	font-size: .6875rem;
	font-variant-numeric: tabular-nums;
	color: var(--color-text-secondary);
}

.log-delete {
	width: 1.75rem;
	height: 1.75rem;
}

.log-delete svg {
	width: 1rem;
	height: 1rem;
}

.log-add {
	margin-top: .75rem;
	padding-top: .75rem;
	border-top: 1px solid var(--color-tile-separator);
}

.log-add .button {
	margin-top: .65rem;
}

/* A full-width button inside a tile stays the size of the other controls */
.button-block.button-small {
	min-height: 2.25rem;
	border-radius: 1.125rem;
	font-size: .9375rem;
}

.button-block.button-small svg {
	width: 1.1rem;
	height: 1.1rem;
}

/* ---------- Free text in a tile ---------- */
.field-textarea {
	height: auto;
	min-height: 4.5rem;
	padding: .55rem .75rem;
	line-height: 1.3rem;
	resize: vertical;
}

/* ---------- Planning pop-up ---------- */
.sheet-narrow {
	width: min(calc(100% - 2rem), 25rem);
}

.booking-subject {
	margin: 0 1rem .75rem;
	font-size: .875rem;
	font-weight: 500;
	color: var(--color-label-secondary);
}

/* "Van 21 sep tot 25 sep" on one line, so the period is one thing you read at a
   glance rather than two form fields. */
.date-range {
	flex-wrap: wrap;
	gap: .4rem;
	justify-content: flex-start;
}

.date-range-word {
	color: var(--color-label-secondary);
}

.button-spaced {
	margin-top: .6rem;
}

/* ---------- Notice pop-up (e.g. "wrong file type") ---------- */
.notice {
	width: min(calc(100% - 2rem), 20rem);
}

.notice .settings-inner {
	padding: 1.5rem 1.25rem 1.25rem;
	text-align: center;
}

.notice h2 {
	margin: 0 0 .4rem;
	font-size: 1.0625rem;
	font-weight: 600;
}

.notice p {
	margin: 0 0 1.25rem;
	font-size: .9375rem;
	line-height: 1.3rem;
	color: var(--color-label-secondary);
}

/* Narrow phones: give the search and the filter a line of their own.
   ("Job types" used to be a header button that shrank to its icon here; it lives in
   the functions menu now, where it keeps its label.) */
@media (max-width: 30rem) {
	/* The Users toolbar is a two-row grid by now (see above); this is for any other
	   toolbar that still wraps as a flex row. */
	.toolbar:not(.toolbar-compact) .search,
	.toolbar:not(.toolbar-compact) .filter {
		flex-basis: 100%;
		max-width: none;
	}

	[data-page="users"] .filter label > span {
		gap: .2rem;
		padding: 0 .4rem;
	}
}

/* ---------- Login screen ---------- */
/* The column is never wider than the screen (Oct 21): a field with buttons in it (the
   new password's eye and copy) made the card as wide as its widest content otherwise */
.auth {
	position: fixed;
	inset: 0;
	z-index: 100;
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	place-items: center;
	padding: max(1rem, env(safe-area-inset-top)) 1rem max(1rem, env(safe-area-inset-bottom));
	overflow-y: auto;
	background: var(--color-page);
}

/* While checking whether someone is already logged in: cover the app, show nothing */
.auth.loading .auth-card {
	visibility: hidden;
}

.auth-card {
	width: min(100%, 24rem);
	padding: 2rem 1rem 1.25rem;
	border-radius: 2rem;
	corner-shape: squircle;
	color: var(--color-label);
	background: var(--color-sheet);
	font-size: 1.0625rem;
	line-height: 1.375rem;
}

.auth-logo {
	width: fit-content;
	margin: 0 auto 1.5rem;
	padding: .55rem 1.1rem;
	border-radius: 1rem;
	font-size: 1.3rem;
	font-weight: 700;
	letter-spacing: .02em;
	color: var(--color-on-banner);
	background: var(--color-banner);
}

.auth-title {
	margin: 0 0 .5rem;
	font-size: 1.5rem;
	font-weight: 700;
	text-align: center;
	letter-spacing: -.015em;
}

.auth-text {
	margin: 0 1rem 1.25rem;
	font-size: .9375rem;
	text-align: center;
	color: var(--color-label-secondary);
}

.auth-title + .settings-group {
	margin-top: 1.25rem;
}

.auth-success {
	margin: 0 1rem 1rem;
	font-size: .9375rem;
	color: var(--color-success);
}

.auth-success:empty {
	display: none;
}

.auth-link {
	display: block;
	margin: 1rem auto 0;
	padding: .5rem;
	font-size: .9375rem;
	color: var(--color-link);
}

.auth-link:hover {
	text-decoration: underline;
}

/* ---------- The accounts on this device (auth.js, Sep 30) ---------- */
/* The same compact rows on the login screen and in the settings: photo (or initials),
   "V. Achternaam", "Actief" on the one in use, and a round × on the right to take one off.
   A tap on a row logs in as that account. */
.auth-accounts {
	margin: 1.25rem 0 1rem;
}

.auth-accounts-title {
	margin: 0 1rem .4rem;
	font-size: .8125rem;
	font-weight: 600;
	color: var(--color-label-secondary);
}

.auth-account {
	position: relative;
	display: flex;
	align-items: center;
	gap: .25rem;
	padding-right: .55rem;
	background: var(--color-group);
	transition: background-color .15s ease-in-out;
}

.auth-account + .auth-account::before,
.auth-account + .auth-account-add::before {
	content: "";
	position: absolute;
	top: 0;
	left: .85rem;
	right: .85rem;
	height: 1px;
	background: var(--color-separator);
}

.auth-account:not(.is-active):hover {
	background: var(--color-group-hover);
}

.auth-account-pick {
	flex: 1;
	min-width: 0;
	display: flex;
	align-items: center;
	gap: .6rem;
	min-height: 2.6rem;
	padding: .3rem 0 .3rem .85rem;
	font-size: .9375rem;
	text-align: left;
}

.auth-account.is-active .auth-account-pick {
	cursor: default;
}

.auth-account-name {
	flex: 1;
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-weight: 500;
}

/* The one in use */
.auth-account-active {
	flex-shrink: 0;
	margin-right: .35rem;
	font-size: .75rem;
	font-weight: 600;
	color: var(--color-link);
}

/* The × with a round grey background: clearly the part of the row that removes */
.auth-account-remove {
	display: grid;
	flex-shrink: 0;
	place-items: center;
	width: 1.6rem;
	height: 1.6rem;
	border-radius: 50%;
	color: var(--color-label-secondary);
	background: var(--color-fill);
	transition: background-color .15s ease-in-out, color .15s ease-in-out;
}

.auth-account-remove:hover {
	color: var(--color-destructive);
	background: var(--color-close-hover);
}

.auth-account-remove svg {
	width: .85rem;
	height: .85rem;
	stroke-width: 2.2;
}

/* "+ Account toevoegen" under the list in the settings, as low as the rows */
.auth-account-add {
	min-height: 2.6rem;
	font-size: .9375rem;
}

.auth-account-add svg {
	width: 1rem;
	height: 1rem;
	stroke-width: 2;
}

/* With accounts above it, the fields don't need the extra room under the title */
.auth-accounts:not([hidden]) + .settings-group {
	margin-top: 0;
}

/* ---------- Logging in with a code (auth.js, Oct 21) ---------- */
/* "Inloggen met code" under "Wachtwoord vergeten?", a little closer to it */
.auth-link + .auth-link {
	margin-top: 0;
}

/* The code: shown in capitals with a little room between them, as it is in the e-mail
   (only once something is typed; the placeholder stays as written) */
[data-auth-field="code"] input:not(:placeholder-shown) {
	text-transform: uppercase;
	letter-spacing: .06em;
}

/* The welcome screen's e-mail: the login's own, not something to type in */
#auth-form .field-row input:read-only {
	color: var(--color-label-secondary);
}

/* The eye and the copy button at the end of the new password field */
.auth-password-row {
	gap: .25rem;
	padding-right: .45rem;
}

.auth-password-row input {
	margin-right: .5rem;
}

.auth-field-tool {
	display: grid;
	flex-shrink: 0;
	place-items: center;
	width: 2.25rem;
	height: 2.25rem;
	border-radius: 50%;
	color: var(--color-label-secondary);
	transition: background-color .15s ease-in-out, color .15s ease-in-out;
}

.auth-field-tool:hover {
	color: var(--color-link);
	background: var(--color-fill);
}

.auth-field-tool svg {
	width: 1.2rem;
	height: 1.2rem;
	stroke-width: 1.9;
}

/* The eye shows what it will do: open while hidden, struck through while shown */
.auth-field-tool .auth-eye-closed,
.auth-field-tool.is-shown .auth-eye-open {
	display: none;
}

.auth-field-tool.is-shown .auth-eye-closed {
	display: block;
}

/* ---------- Toast ---------- */
.toast {
	position: fixed;
	left: 50%;
	bottom: max(1.25rem, env(safe-area-inset-bottom));
	z-index: 200;
	width: max-content;
	max-width: calc(100% - 2rem);
	padding: .7rem 1.1rem;
	border-radius: 1.25rem;
	font-size: .9375rem;
	font-weight: 500;
	color: var(--color-on-toast);
	background: var(--color-toast);
	box-shadow: 0 .5rem 1.5rem var(--color-toast-shadow);
	opacity: 0;
	translate: -50% .5rem;
	pointer-events: none;
	transition: opacity .25s ease-in-out, translate .25s ease-in-out;
}

.toast.show {
	opacity: 1;
	translate: -50% 0;
}

/* ---------- The list, broken up by week ---------- */
/* An admin can be looking at sixty hour papers in a busy week. One heading per week,
   with that week's cards in their own .tiles container underneath, so the heading
   runs the full width of the page instead of sitting in a column. */
.week-list {
	display: flex;
	flex-direction: column;
	gap: 1.1rem;
}

.week-group {
	display: flex;
	flex-direction: column;
	gap: .55rem;
}

/* The whole divider is the button that folds the week shut: it is the easiest thing
   on the page to hit, and the arrow on the end says what it does. */
.week-break {
	display: flex;
	align-items: center;
	gap: .55rem;
	width: 100%;
	margin: 0;
	padding: .15rem .2rem;
	font-size: .8125rem;
	font-weight: 700;
	letter-spacing: .09em;
	text-transform: uppercase;
	text-align: left;
	color: var(--color-link);
}

/* One width for every week label, so the rules after them all start at the same
   point down the list (Oct 20). tabular-nums gives every digit the same
   width (WEEK 41 is otherwise narrower than WEEK 42); min-width covers the widest
   label, "HAFTA 52". Only the undated group's label ("Geen datum") is longer. */
.week-break-label {
	flex-shrink: 0;
	min-width: 6em;
	font-variant-numeric: tabular-nums;
}

/* How many cards a month or year divider holds (the week dividers dropped their
   count on Oct 20) */
.week-break-count {
	font-weight: 600;
	letter-spacing: 0;
	color: var(--color-text-secondary);
}

/* The rule is what makes this read as a break in the list rather than a title
   belonging to the first card. Blue like the label, a whole pixel as a border: 1.5px
   drew some rules 1px and others 2px, depending on where each one landed on the
   screen's pixel grid (Oct 20; 2px was tried and was too heavy). */
.week-break-rule {
	flex: 1;
	height: 0;
	/* The label's blue, faded: the % is how much blue, the rest is see-through */
	border-top: 1px solid color-mix(in srgb, var(--color-link) 50%, transparent);
}

.week-break-arrow {
	flex-shrink: 0;
	width: 1.05rem;
	height: 1.05rem;
	stroke-width: 2.4;
	color: var(--color-text-secondary);
	transition: rotate .2s ease-in-out, color .15s ease-in-out;
}

/* Blue like the week label, always (Oct 20; it was grey until hovered). The month and
   year dividers keep their grey arrow. */
.week-break .week-break-arrow {
	color: var(--color-link);
}

/* Folded shut: the arrow points at the week it would open */
.week-group.is-collapsed .week-break-arrow {
	rotate: -90deg;
}

.week-group.is-collapsed > .tiles {
	display: none;
}

/* ---------- Cards, tightened ---------- */
/* The lines on a card are one thing to read, not a form: they sit right under each
   other. Asked for twice — lean tight. */
.card-tight {
	padding: .75rem .9rem .8rem;
}


.card-line {
	margin: 0;
	font-size: .875rem;
	line-height: 1.2rem;
	overflow-wrap: anywhere;
	color: var(--color-text-secondary);
}

.card-line-strong {
	font-weight: 500;
	color: var(--color-text);
}


.card-tight .card-actions {
	margin-top: .6rem;
}

/* Week and dates on one line: the number is what you look for, the dates confirm it */
.card-week .card-open {
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: .1rem .5rem;
}

.card-week-number {
	font-size: 1.0625rem;
	font-weight: 650;
}

.card-week-dates {
	font-size: .8125rem;
	font-weight: 500;
	font-variant-numeric: tabular-nums;
	color: var(--color-text-secondary);
}

.card-dates {
	margin-top: .15rem;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
}

.card-numbers {
	display: flex;
	align-items: center;
	gap: .6rem;
	font-size: .875rem;
	font-variant-numeric: tabular-nums;
}

.card-numbers b {
	font-weight: 650;
}

/* Copy on the left as an icon, then edit and hand in */
.card-actions-hours {
	grid-template-columns: auto 1fr 1fr;
}

/* One button on its own takes the width rather than half of it */
.card-actions-single {
	grid-template-columns: 1fr;
}

/* ---------- Card layout ---------- */
/* Two rows, not two columns. The head — the week and its dates, or the title — gets
   the whole width up to the buttons, because it is one thing you read in one go and
   in a half-width column the dates kept dropping onto a line of their own. Only the
   detail lines underneath share their row, with the numbers on the right. */
.card-head {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: .6rem;
}

.card-head .card-title {
	flex: 1;
	min-width: 0;
}

.card-body {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: .5rem .75rem;
	margin-top: .1rem;
}

.card-main {
	min-width: 0;
}

.card-body .card-numbers {
	flex-shrink: 0;
}

/* The round buttons are taller than the week title next to them. Pulled into the
   card's padding (Sep 30), so they no longer push the lines underneath down: the
   head is as tall as its title, and the card as short as its lines. */
.card-head .card-buttons {
	margin-block: -.2rem;
}

/* A project card has no numbers column: its lines sit straight under the title */
.card-project .card-main {
	margin-top: .1rem;
}

/* Every card of a kind is the same height (Sep 30): a fixed number of lines, empty
   ones included (cardLinesHtml), and nothing that wraps onto a second line — a long
   name or street ends in an ellipsis instead. The details sheet has it in full. */
.card-main .card-line,
.card-project .card-open {
	display: block;
	max-width: 100%;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

/* Above the invisible layer that makes the whole card tappable */
.card-buttons {
	position: relative;
	z-index: 1;
	display: flex;
	gap: .3rem;
}

.card-button {
	display: grid;
	place-items: center;
	width: 1.85rem;
	height: 1.85rem;
	border-radius: 50%;
	color: var(--color-text);
	background: var(--color-sort-direction);
	transition: background-color .15s ease-in-out;
}

.card-button:hover {
	background: var(--color-sort-direction-hover);
}

.card-button svg {
	width: 1rem;
	height: 1rem;
	stroke-width: 2;
}

/* Handing in is the one that finishes the week, so it is the one that is filled in */
.card-button-primary {
	color: var(--color-on-button-primary);
	background: var(--color-button-primary);
}

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

/* The status as a bar instead of a chip on a row of its own: the colour is the whole
   message, and the row it used to cost is now white space. It sits *inside* the card
   with its own rounded ends, not painted along the card's edge. */
.card[data-mark] {
	padding-left: 1.3rem;
}

.card[data-mark]::before {
	content: "";
	position: absolute;
	top: .75rem;
	bottom: .75rem;
	left: .45rem;
	width: .28rem;
	border-radius: .2rem;
	background: var(--color-mark-draft);
}

/* Uurbon (Sep 30, swapped): a concept in the colour of its company (--mark-color, set by
   hours.js), or the light blue when the company has none; handed in (waiting) is the
   quiet grey. Approved and rejected keep their green and red. */
.card[data-mark="draft"]::before { background: var(--mark-color, var(--color-mark-waiting)); }
.card[data-mark="waiting"]::before { background: var(--color-mark-draft); }
.card[data-mark="ok"]::before { background: var(--color-mark-ok); }

/* A project card has no status to show any more: its company's colour (--mark-color,
   set on the card by assignments.js, migration 032), or a quiet grey when the company
   has none. A cancelled one stays red. */
.card-project[data-mark="ok"]::before { background: var(--mark-color, var(--color-mark-project)); }
.card[data-mark="denied"]::before { background: var(--color-mark-denied); }

/* The chips sit together on one line, so a card that is both archived and rejected
   does not grow a row for each */
.card-chips {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	justify-content: flex-end;
	gap: .25rem;
}

/* Whose week it is, on the same line as the hours rather than a line of its own.
   Raised above the invisible layer that makes the card tappable, so a tap on it
   answers with the name instead of opening the card. */
.card-avatar {
	position: relative;
	z-index: 1;
	width: 1.6rem;
	height: 1.6rem;
	font-size: .625rem;
	box-shadow: 0 0 0 2px var(--color-card);
	cursor: pointer;
}

/* The OP number leads the three lines of detail, so it is the one that is not grey */
p.card-op {
	font-weight: 600;
	letter-spacing: .01em;
	color: var(--color-text);
}

/* ---------- Archive ---------- */
/* Why something is in the archive, next to what it was when it got there */
.chip-archive-deleted { color: var(--color-on-status-completed); background: var(--color-status-completed); }
.chip-archive-denied { color: var(--color-on-status-denied); background: var(--color-status-denied); }

/* ---------- Wheel fields ---------- */
/* The pill that shows the value, and the wheel that picks it. Made for the hours on
   an uurbon: half an hour at a time, one flick from end to end. */
.wheelfield {
	position: relative;
	min-width: 0;
}

.wheelfield-button {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 2rem;
	padding: 0 .35rem;
	border-radius: .5rem;
	corner-shape: squircle;
	font: inherit;
	font-size: .875rem;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
	color: var(--color-label);
	background: var(--color-fill);
	transition: background-color .15s ease-in-out, box-shadow .15s ease-in-out;
}

.wheelfield-button:hover {
	background: var(--color-close-hover);
}


/* Nothing filled in yet: the dash is quieter than a number */
.wheelfield-value.is-empty {
	font-weight: 500;
	color: var(--color-placeholder);
}

/* ---------- The wheel pop-up ---------- */
/* A popover, so it draws above the pop-up it was opened from (same as the calendar). */
.wheel {
	/* One row. The list is five of these tall and the pads are two each, which is
	   what puts the chosen row exactly in the middle. */
	--wheel-item: 1.85rem;
	--wheel-rows: 7;
	position: fixed;
	width: 8.5rem;
	margin: 0;
	padding: 0;
	overflow: hidden;
	border: 0;
	border-radius: 1.1rem;
	corner-shape: squircle;
	color: var(--color-text);
	background: var(--color-menu);
	box-shadow: 0 10px 30px var(--color-menu-shadow);
}

.wheel:popover-open {
	display: flex;
}

/* The wheel itself: the band and the list share this box, so the band stays centred
   on the list when the quick picks sit beside it. */
.wheel-main {
	position: relative;
	flex: 1;
	min-width: 0;
}

/* The band the chosen value sits under: one row tall, dead centre */
.wheel-band {
	position: absolute;
	top: 50%;
	left: .4rem;
	right: .4rem;
	height: var(--wheel-item);
	translate: 0 -50%;
	border-radius: .6rem;
	corner-shape: squircle;
	background: var(--color-fill);
	pointer-events: none;
}

/* The fade at the top and bottom is what makes this read as a wheel turning rather
   than a list scrolling. */
.wheel-list {
	position: relative;
	height: calc(var(--wheel-item) * var(--wheel-rows));
	overflow-y: auto;
	overscroll-behavior: contain;
	scroll-snap-type: y mandatory;
	-webkit-mask-image: linear-gradient(#00000000, #000000 14%, #000000 86%, #00000000);
	mask-image: linear-gradient(#00000000, #000000 14%, #000000 86%, #00000000);
}

.wheel-pad {
	height: calc(var(--wheel-item) * (var(--wheel-rows) - 1) / 2);
}

/* Left-aligned, so the hours start in one straight line down the wheel */
.wheel-item {
	display: flex;
	align-items: baseline;
	justify-content: flex-start;
	gap: .25em;
	width: 100%;
	height: var(--wheel-item);
	padding: 0 1rem;
	line-height: var(--wheel-item);
	scroll-snap-align: center;
	font-size: .9375rem;
	font-weight: 500;
	font-variant-numeric: tabular-nums;
	color: var(--color-text-secondary);
	transition: color .12s ease-in-out;
}

.wheel-item.is-centred {
	font-weight: 700;
	color: var(--color-text);
}

/* "30 min" a size smaller than the hours in front of it, in the wheel and on the pill */
.hours-minutes {
	font-size: .78em;
	font-weight: inherit;
}

.wheelfield-value .hours-minutes {
	margin-left: .2em;
}

/* The half hour in the wheel: '8.30', the '.30' a size smaller and a hair apart */
.wheel-half {
	font-size: .8em;
}

/* The hours in a column of their own, right-aligned, and the '.30' in a fixed-width
   slot after them: 3, 3.30 and 4 all put their digit in the same place (Sep 23).
   Both slots are there on every row, also when one is empty. */
.wheel-hour {
	text-align: left;
}

/* Quick picks: the left half of the pop-up, on every screen — one tap is faster
   than any flick. The wheel takes the right half. The buttons are tall enough to hit
   with a thumb, and the wheel is as tall as their column: nine rows instead of seven,
   each a little shorter, so more hours are in sight at once. */
.wheel.has-quick {
	--wheel-item: 1.7rem;
	--wheel-rows: 9;
	width: 10.5rem;
}

.wheel-quick {
	display: flex;
	flex: 0 0 50%;
	flex-direction: column;
	justify-content: center;
	gap: .3rem;
	padding: .45rem 0 .45rem .45rem;
}

/* Left-aligned: every row's first digit starts at the same line, whether the number
   is 8, 12 or 12.30 — and the left edge is the part a thumb on the wheel leaves in
   sight (Sep 23). */
.wheel.has-quick .wheel-item {
	justify-content: flex-start;
	gap: 0;
	padding: 0 .4rem 0 1rem;
}

.wheel-quick-item {
	flex: 1;
	max-height: 2.6rem;
	border-radius: .5rem;
	corner-shape: squircle;
	font-size: .9375rem;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
	color: var(--color-text);
	background: var(--color-fill);
	transition: background-color .12s ease-in-out;
}

.wheel-quick-item:hover {
	background: var(--color-menu-hover);
}

.wheel-quick-item.is-current {
	color: var(--color-on-button-primary);
	background: var(--color-button-primary);
}

/* ---------- Compact pop-up ---------- */
/* The pop-ups are iOS Settings sized (52px rows, 17px text), which is right for a
   handful of switches and wrong for a form with fifteen rows: the uurbon would run
   over two and a half screens on a phone. This trims the same styling down so the
   whole week can be taken in at a glance, without turning it into a different look. */
.sheet-compact .settings-inner {
	padding: 1rem .85rem 1.1rem;
	font-size: .9375rem;
	line-height: 1.25rem;
}

.sheet-compact .settings-head {
	grid-template-columns: 2.25rem 1fr 2.25rem;
	margin: -1rem -.85rem .4rem;
	padding: .85rem .85rem .6rem;
}

.sheet-compact .settings-head h2 {
	font-size: 1rem;
}

/* A header with buttons in it lays out as a row instead of the usual three-column
   grid: fixed side columns would either crush the title or push the buttons off the
   edge on a phone. The title still centres itself in whatever room is left. */
/* Close on the left, buttons on the right, and the title centred on the sheet — not on
   the space left between them. Both side columns ask for at least their own content
   and otherwise share the rest equally, so with a wide Save button the title still
   sits in the middle; only when there really isn't room does it give way (and cut off
   with an ellipsis) rather than push the buttons off the edge. */
.settings-head:has(.settings-head-actions) {
	display: grid;
	grid-template-columns: minmax(max-content, 1fr) minmax(0, auto) minmax(max-content, 1fr);
	align-items: center;
	gap: .5rem;
}

.settings-head:has(.settings-head-actions) > .settings-close {
	grid-column: 1;
	grid-row: 1;
	justify-self: start;
}

.settings-head:has(.settings-head-actions) > .settings-head-actions {
	grid-column: 3;
	grid-row: 1;
	justify-self: end;
}

.settings-head:has(.settings-head-actions) h2 {
	flex: 1;
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.settings-head-actions {
	display: flex;
	flex-shrink: 0;
	align-items: center;
	gap: .3rem;
}

/* "Opgeslagen" on the left (the uurbon form, Oct 20): in the close button's cell, just
   past it — the margin is the close button (2.25rem in a compact sheet) plus a gap.
   Being in that cell, it also makes the left column wide enough for itself. */
.settings-head:has(.settings-head-actions) > .settings-head-status {
	grid-column: 1;
	grid-row: 1;
	justify-self: start;
	display: flex;
	margin-left: calc(2.25rem + .45rem);
}

.settings-head-status .autosave-status {
	margin-right: 0;
}

.sheet-compact .settings-close {
	width: 2.25rem;
	height: 2.25rem;
}

.sheet-compact .settings-close svg {
	width: 1.05rem;
	height: 1.05rem;
}

.sheet-compact .settings-label {
	margin: 1rem 0 .3rem;
	padding: 0 .85rem;
	font-size: .875rem;
}

.sheet-compact .settings-group {
	border-radius: 1.25rem;
}

.sheet-compact .field-row,
.sheet-compact .settings-row {
	min-height: 2.6rem;
	padding-inline: .85rem;
}

.sheet-compact .field-row + .field-row::before,
.sheet-compact .settings-row + .settings-row::before,
.sheet-compact .field-row + .settings-row::before,
.sheet-compact .settings-row + .field-row::before {
	left: .85rem;
	right: .85rem;
}

.sheet-compact .form-error {
	margin: .6rem .85rem .4rem;
}

.sheet-compact .button-block {
	min-height: 2.9rem;
	border-radius: 1.45rem;
	font-size: 1rem;
}

/* ---------- Hour paper (uurbon) ---------- */
/* Everything here is built to fit a phone held in one hand: the whole week is one
   screen, and every row says the same four things in the same four places. */

/* The week decides the date on every row below it, so it sits above them all.
   Sep 29: the week pill on the left, the two arrows right beside it, all three the
   same height. The pill is the main colour pulled most of the way to grey; the arrows
   are black on white. */
.week-stepper {
	--week-height: 2.1rem;
	display: flex;
	align-items: center;
	gap: .35rem;
	margin-bottom: .75rem;
}

.week-stepper-pill {
	display: flex;
	flex-shrink: 0;
	align-items: center;
	justify-content: center;
	min-width: 7.5rem;
	height: var(--week-height);
	padding: 0 1.1rem;
	border-radius: 999px;
	corner-shape: round;
	color: var(--color-on-week-pill);
	background: var(--color-week-pill);
}

.week-stepper-week {
	font-size: 1rem;
	font-weight: 650;
	white-space: nowrap;
}

.week-stepper-arrows {
	display: flex;
	flex-shrink: 0;
	gap: .35rem;
}

/* Black on white (the white of the groups, so a dark grey in the dark theme) */
.week-stepper .icon-pill {
	width: var(--week-height);
	height: var(--week-height);
	color: var(--color-label);
	background: var(--color-group);
}

.week-stepper .icon-pill:hover {
	background: var(--color-close-hover);
}

/* The base .icon-pill draws filled shapes (the ⋯ dots); these are drawn lines */
.week-stepper .icon-pill svg {
	width: 1.25rem;
	height: 1.25rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 2.3;
}

/* One line per day: name, date, hours, parking. The totals row underneath uses the
   same four columns, so both numbers can be read straight down. */
.hours-day {
	display: grid;
	grid-template-columns: 2.2rem minmax(0, 1fr) 7rem 4.4rem;
	align-items: center;
	gap: .3rem;
	min-height: 2.6rem;
	padding: 0 .55rem 0 .75rem;
}

/* Says what the four columns are. Quiet, short, and the only row with no value in
   it — long words (Otopark ücreti) get two lines rather than an ellipsis. */
.hours-day.hours-head {
	min-height: 0;
	padding-top: .5rem;
	padding-bottom: .35rem;
	font-size: .6875rem;
	font-weight: 600;
	line-height: 1.1;
	letter-spacing: .01em;
	color: var(--color-label-secondary);
}

/* Hours read from the left, like the value in the pill under them; parking stays
   centred over its field */
.hours-head span:nth-child(3) {
	padding-left: .6rem;
}

.hours-head span:nth-child(4) {
	text-align: center;
}

/* On the form (Sep 29): the header row had narrower side padding than the day rows
   (those are .field-row, .85rem in a compact sheet), so its columns sat a few pixels
   to the left of the fields. Same padding now, and "Uren" and "Parkeergeld" start
   exactly where the grey field under them starts (left-aligned). */
:is(#hours-form-days, #hours-sheet) .hours-head {
	padding-inline: .85rem;
}

:is(#hours-form-days, #hours-sheet) .hours-head span:nth-child(3),
:is(#hours-form-days, #hours-sheet) .hours-head span:nth-child(4) {
	justify-self: start;
	padding-left: 0;
	text-align: left;
}

/* A row under a separator line: the line takes the row's top pixel, so that row is
   a pixel taller with the pixel on top — the hour and parking fields then sit exactly
   halfway between the line above and the line below (Sep 29) */
:is(#hours-form-days, #hours-sheet .settings-group) > .hours-day:not(.hours-head) + .hours-day {
	min-height: calc(var(--hours-row-height) + 1px);
	padding-top: 1px;
}

/* ---------- Uurbon: compact day rows (Oct 20) ---------- */
/* The space between "ma" and "di" was not padding or margin: a day row has no padding
   top or bottom. It was min-height — every row in a compact pop-up is at least 2.6rem
   (.sheet-compact .field-row), however little is in it — with the 2rem grey fields as
   the floor under that. Both are set here, in one place, for the uurbon form and the
   read-only uurbon. The ID makes these win over .sheet-compact .field-row. */
:is(#hours-form-sheet, #hours-sheet) {
	--hours-row-height: 2.125rem;   /* a day row is never shorter than this */
	--hours-field-height: 1.625rem; /* the grey hour and parking fields inside it */
	--hours-pick-row-height: 2.375rem; /* Werknemer, Project, Bedrijf, Teamleider */
	--hours-pick-button-size: 1.875rem; /* their round button or photo; fits the row, which stays the same */
	--hours-group-gap: .4rem;       /* between those four groups */
}

/* The four groups at the top, the same way (Oct 20): the row was min-height 2.6rem
   with a 1.9rem round button in it, and the "Naam / E-mail / Telefoon" lines under it
   had padding above and below plus a little gap between the lines */
:is(#hours-form-sheet, #hours-sheet) .hours-pick-group .field-row {
	min-height: var(--hours-pick-row-height);
}

:is(#hours-form-sheet, #hours-sheet) .hours-pick-group :is(.hours-pick-button, .company-arrow, .hours-view-avatar) {
	width: var(--hours-pick-button-size);
	height: var(--hours-pick-button-size);
}

:is(#hours-form-sheet, #hours-sheet) .hours-pick-group :is(.hours-pick-button, .company-arrow) svg {
	width: .9rem;
	height: .9rem;
}

:is(#hours-form-sheet, #hours-sheet) .hours-pick-group .company-info {
	padding-block: .35rem .4rem;
	row-gap: 0;
	line-height: 1.05rem;
}

:is(#hours-form-sheet, #hours-sheet) .settings-group + .settings-group {
	margin-top: var(--hours-group-gap);
}

:is(#hours-form-sheet, #hours-sheet) .field-row.hours-day {
	min-height: var(--hours-row-height);
}

:is(#hours-form-sheet, #hours-sheet) .hours-day :is(.wheelfield-button, .hours-parking, .hours-view-field) {
	height: var(--hours-field-height);
}

/* The header belongs to the table, not to the rows: no separator line under it */
.hours-head + .settings-row::before,
.hours-head + .field-row::before {
	content: none;
}

/* The smallest phones still in use (iPhone SE, 320px). Turkish weekday and month
   names are the widest of the three languages, and "26 Eyl" has to fit whole. */
@media (max-width: 22.5rem) {
	.hours-day {
		grid-template-columns: 2rem minmax(0, 1fr) 5.45rem 3.7rem;
		gap: .2rem;
		padding-inline: .55rem .4rem;
	}

	/* 14.09.2026 is ten characters and has to fit whole next to the wheel */
	.hours-day-date {
		font-size: .75rem;
		letter-spacing: -.02em;
	}

	.hours-day :is(.wheelfield-button, .hours-view-field:not(.hours-parking)) {
		padding-inline: .4rem .15rem;
		font-size: .8125rem;
	}

	.hours-head span:nth-child(3),
	.hours-total-hours {
		padding-left: .4rem;
	}
}

.hours-day-name {
	font-size: .9375rem;
	font-weight: 650;
}

.hours-day-date {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-size: .8125rem;
	font-variant-numeric: tabular-nums;
	color: var(--color-label-secondary);
}

/* Saturday and Sunday are on the paper form too, but they are the exception */
.hours-day.is-weekend .hours-day-name,
.hours-day.is-weekend .hours-day-date {
	color: var(--color-day-weekend);
}

/* Parking money: a small field of its own, so it is clearly not part of the hours */
.hours-parking {
	display: flex;
	align-items: center;
	gap: .2rem;
	height: 2rem;
	padding: 0 .45rem;
	border-radius: .5rem;
	corner-shape: squircle;
	background: var(--color-fill);
	transition: box-shadow .15s ease-in-out;
}

.hours-parking-sign {
	flex-shrink: 0;
	font-size: .8125rem;
	color: var(--color-label-secondary);
}

/* Two classes: the plain .field-row input further up the file sets font: inherit,
   which would put the size back to the row's own. */
.field-row .hours-parking-input {
	width: 100%;
	min-width: 0;
	font-size: .875rem;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	text-align: left;
}

.field-row .hours-parking-input::placeholder {
	font-weight: 500;
	color: var(--color-placeholder);
}

/* The two sums, never typed in */
/* The two sums are read off the paper, not typed into it, so they sit on the white
   like everything else and only the weight sets them apart. */
.hours-total {
	font-weight: 650;
	background: var(--color-group);
}

.hours-total-label {
	grid-column: 1 / 3;
	font-size: .9375rem;
}

.hours-total-hours,
.hours-total-parking {
	font-size: .875rem;
	font-variant-numeric: tabular-nums;
	text-align: center;
}

.hours-total-hours {
	padding-left: .6rem;
	text-align: left;
}

/* The OP is fixed and drawn in front of the field, so only the six digits are typed */
.op-field {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	min-width: 0;
	margin-left: auto;
}

/* No gap and the same weight as the digits: an OP number is written OP240117, in
   one piece, and it should read that way even though half of it is a field. */
.op-prefix {
	flex-shrink: 0;
	/* Same letter spacing as the digits, and a little air before them, so "OP" and the
	   number read as two parts of one code instead of the P touching the first digit */
	margin-right: .12em;
	font-variant-numeric: tabular-nums;
	letter-spacing: .01em;
	color: var(--color-label-secondary);
}

/* Exactly six digits wide, so OP240117 ends flush against the row's right edge the
   way the plain values in the rows above and below it do. */
.field-row .op-field input {
	flex: 0 0 auto;
	width: calc(6ch + .15em);
	font-variant-numeric: tabular-nums;
	letter-spacing: .01em;
	text-align: left;
	color: var(--color-label-secondary);
}

/* Export: round, quiet, and in the header rather than on the paper, so it can never
   be mistaken for part of the uurbon. Nothing behind it yet. */
.icon-pill-export {
	width: 2.25rem;
	height: 2.25rem;
	color: var(--color-close-icon);
	background: var(--color-close);
}

.icon-pill-export:hover {
	background: var(--color-close-hover);
}

.icon-pill-export svg {
	width: 1.15rem;
	height: 1.15rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 2;
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* A line under the save button, for something worth saying once */
.form-note {
	margin: .5rem .85rem 0;
	font-size: .8125rem;
	line-height: 1.1rem;
	text-align: center;
	color: var(--color-label-secondary);
}

/* ---------- Signatures ---------- */
/* Always paper-white with dark ink, in both themes: a signature ends up in the
   office's records and on a printout, where a white-on-black one would be gone. */
.signature {
	position: relative;
	padding: .65rem .85rem .85rem;
	background: var(--color-group);
}

.signature + .signature::before {
	content: "";
	position: absolute;
	top: 0;
	left: .35rem;
	right: .35rem;
	height: 1px;
	background: var(--color-separator);
}

.signature-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: .5rem;
	margin-bottom: .4rem;
}

.signature-label {
	font-size: .8125rem;
	font-weight: 500;
	color: var(--color-text-secondary);
}

/* Only offered once there is something to wipe out */
.signature-clear {
	font-size: .8125rem;
	font-weight: 600;
	color: var(--color-link);
	opacity: 0;
	pointer-events: none;
	transition: opacity .15s ease-in-out;
}

.signature.has-ink .signature-clear {
	opacity: 1;
	pointer-events: auto;
}

.signature-pad {
	display: block;
	width: 100%;
	height: 9.4rem;
	border-radius: .55rem;
	corner-shape: squircle;
	background: #ffffff;
	box-shadow: inset 0 0 0 1px var(--color-separator);
	/* Without this the pop-up scrolls under the finger that is signing */
	touch-action: none;
	cursor: crosshair;
}

/* ---------- Hour paper, read back (#hours-sheet, Sep 30) ---------- */
/* Built from the form's own parts (hours.js, hoursView…): the week pill, the four
   pick groups, the day rows and the signature boxes. Only what can't be typed into
   is new here: the values stand where the inputs stand in the form. */

/* The status chip on a line of its own above the week, left-aligned with the pill */
.hours-view-status {
	display: flex;
	margin-bottom: .5rem;
}

/* The week pill without its arrows, the dates beside it */
.hours-view-dates {
	min-width: 0;
	padding-left: .25rem;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-size: .875rem;
	font-weight: 500;
	font-variant-numeric: tabular-nums;
	color: var(--color-label-secondary);
}

/* The reference and when it was last saved: small and grey under the hours table, in
   line with the rows' text, for whoever needs to quote it */
.hours-view-meta {
	margin: .45rem 0 0;
	padding-left: .85rem;
	font-size: .75rem;
	line-height: 1.05rem;
	color: var(--color-label-secondary);
}

.hours-view-meta p {
	margin: 0;
}

/* The choice on the right, where the form has its input, in the same weight and grey.
   Two classes: .field-row > span would otherwise keep it from shrinking. */
.field-row > .hours-view-choice {
	flex: 1 1 0;
	min-width: 0;
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: .5rem;
}

.hours-view-value {
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-weight: 500;
	color: var(--color-uurbon-value);
}

.hours-view-value.is-empty {
	font-weight: 400;
	color: var(--color-placeholder);
}

/* A linked colleague: their photo where the form has its round person button */
.hours-view-avatar {
	flex-shrink: 0;
	width: 1.9rem;
	height: 1.9rem;
	font-size: .62rem;
}

#hours-sheet .hours-info a {
	color: inherit;
}

/* The hour and parking "fields": the look of the form's, without anything to tap */
.hours-view-field {
	display: flex;
	align-items: center;
	height: 2rem;
	padding-inline: .6rem .35rem;
	border-radius: .5rem;
	corner-shape: squircle;
	font-size: .875rem;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
	color: var(--color-label);
	background: var(--color-hours-field);
}

.hours-view-field.hours-parking {
	padding-inline: .45rem;
}

.hours-view-field .is-empty {
	font-weight: 500;
	color: var(--color-placeholder);
}

/* Every button at the foot of the paper (Sep 30): Indienen, Goedkeuren / Afkeuren /
   Heropenen and Verwijderen, each a button of its own, all the same width, stacked
   and centred. Their colours come from .button-primary and .button-secondary (the
   --color-button-… tokens at the top of the file) and .hours-view-danger below. */
.hours-view-actions {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: .55rem;
	margin-top: 1.4rem;
}

.hours-view-actions .button {
	width: min(100%, 17rem);
	min-height: 2.75rem;
	padding-inline: 1.1rem;
	border-radius: 1.375rem;
	font-size: .9375rem;
}

/* A little more room before the red ones: the answers that undo or throw away sit
   apart from the ones that move the paper forward */
.hours-view-actions .button:not(.hours-view-danger) + .hours-view-danger {
	margin-top: .35rem;
}

/* Afkeuren and Verwijderen: red text on the white of the groups above, like a delete
   row in iOS Settings — clearly a button, quieter than a solid red one, and both still
   ask before they do anything. Was red on a pinkish 16% red until Oct 20 (too
   loud); the red tint now only shows on hover. */
.hours-view-danger {
	color: var(--color-destructive);
	background: var(--color-group);
}

.hours-view-danger:hover:not(:disabled) {
	background: color-mix(in srgb, var(--color-destructive) 8%, var(--color-group));
}

/* The signature on the white of the pad it was drawn on, at the pad's shape */
.signature-view {
	display: block;
	width: 100%;
	aspect-ratio: 900 / 390;
	border-radius: .55rem;
	corner-shape: squircle;
	object-fit: contain;
	background: #ffffff;
	box-shadow: inset 0 0 0 1px var(--color-separator);
}

/* Always on white, so a fixed grey rather than the theme's placeholder colour */
.signature-view-empty {
	display: grid;
	place-items: center;
	font-size: .8125rem;
	font-style: italic;
	color: #a1a1a6;
}

/* Parking money on a card in the list. The P badge is the road sign everybody
   already reads, which saves writing the word out next to a date. */
.card-extra {
	display: flex;
	align-items: center;
	gap: .3rem;
	font-size: .8125rem;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	color: var(--color-text-secondary);
}

/* Its own colours, not a chip's. It used to borrow the "accepted" chip's pair, so it
   turned green the moment that chip did — parking money has nothing to do with a
   status. Starts out the same grey as a draft; change these two and nothing else
   moves. */
.parking-badge {
	display: grid;
	place-items: center;
	width: 1.05rem;
	height: 1.05rem;
	border-radius: .3rem;
	corner-shape: squircle;
	font-size: .6875rem;
	font-weight: 700;
	color: var(--color-on-parking);
	background: var(--color-parking);
}

/* ---------- Wide screens: top panel floats ---------- */
/* The white area hugs the banner (--app-width, .6rem white on each side).
   It floats once there is room for a .6rem gap on both sides (47.2 + 1.2 = 48.4rem),
   and then has all four corners rounded instead of only the bottom two.
   Media queries can't read CSS variables, so 48.4rem is written out here. */
@media (min-width: 48.4rem) {
	:root {
		--radius-content: var(--radius-panel);
	}

	.top {
		width: var(--app-width);
		margin: .6rem auto 0;
		padding-inline: .6rem;
		border-radius: var(--radius-panel);
		/* Top corners use the same squircle curve as the banner, so they run parallel */
		corner-top-left-shape: squircle;
		corner-top-right-shape: squircle;
	}

	/* Browsers without squircle corners: a smaller round corner looks closest */
	@supports not (corner-shape: squircle) {
		.top {
			border-top-left-radius: 1.4rem;
			border-top-right-radius: 1.4rem;
		}
	}
}

/* ---------- Mobile: banner snaps to the screen edges ---------- */
/* The dark blue strip on top is exactly as tall as the notch / Dynamic Island
   (env(safe-area-inset-top)). On phones without one it is 0, so no strip. */
@media (max-width: 39rem) and (orientation: portrait) {
	/* No white panel here: banner and nav straight on the wallpaper. The nav is as far
	   from the page panel as from the banner, and the tab hangs over the panel's top. */
	.top {
		gap: .4rem;
		padding: 0 1rem;
		background: none;
		border-radius: 0;
	}

	.content {
		padding-top: .4rem;
	}

	.banner {
		--banner-radius: 0;
		width: calc(100% + 2rem);
		border-top: env(safe-area-inset-top, 0px) solid var(--color-banner-strong);
		border-radius: 0;
	}

	/* The banner has square corners here, so the logo gets its own small radius */
	.banner-logo {
		border-radius: .55rem;
	}
}

/* ---------- Safari's status bar: banner blue ---------- */
/* Safari on iPhone (iOS 26) no longer reads theme-color. It colours the strip behind
   the clock from a *fixed* element touching the top of the page, and otherwise from
   the page background — which was the grey. A sticky banner was tried first and did
   not count. So: a thin fixed strip in the banner's blue, lying over the top edge of
   the banner itself, where it can't be seen. It has to catch taps (pointer-events
   left on), because Safari finds it by hit-testing the edge; nothing tappable is in
   those few pixels. Phones in portrait only, where the banner reaches the top edge;
   not on the home-screen app, which draws its own strip under the clock. */
.status-tint {
	display: none;
}

@media (max-width: 39rem) and (orientation: portrait) {
	.status-tint {
		display: block;
		position: fixed;
		top: 0;
		left: 0;
		right: 0;
		z-index: 5;
		height: 6px;
		background: var(--color-banner);
	}
}

@media (display-mode: standalone) {
	.status-tint {
		display: none;
	}
}

/* Phones: a little less grey around the panel and a little less white inside it,
   so more of the list fits (Sep 23) */
@media (max-width: 39rem) {
	.content {
		padding-inline: .45rem;
	}

	.panel-head {
		padding: 1rem .75rem .8rem 1rem;
	}

	.panel-body {
		padding: 0 .7rem .7rem;
	}
}

/* ---------- Employee name on an uurbon: typed or picked ---------- */
.employee-row > label {
	flex-shrink: 0;
}

.employee-field {
	display: flex;
	flex: 1;
	align-items: center;
	gap: .4rem;
	min-width: 0;
}

.field-row .employee-field input {
	/* Shrunk to its text by hours.js, so the button sits right in front of the name */
	flex: 0 1 auto;
	text-align: right;
	color: var(--color-label-secondary);
}

.employee-field .employee-pick {
	margin-left: auto;
}

/* Linked to a profile: the name reads as a name, and the button shows their photo */
.field-row .employee-field.is-linked input {
	color: var(--color-label);
}

.employee-pick .employee-avatar {
	width: 100%;
	height: 100%;
	font-size: .6rem;
	color: var(--color-avatar-text);
	background: var(--color-avatar);
	overflow: hidden;
}

.employee-pick .employee-avatar img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.employee-field.is-linked .employee-pick svg {
	display: none;
}

.avatar-tiny {
	width: 1.4rem;
	height: 1.4rem;
	font-size: .55rem;
	color: var(--color-avatar-text);
	background: var(--color-avatar);
	overflow: hidden;
}

.avatar-tiny img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.employee-pick {
	display: grid;
	flex-shrink: 0;
	place-items: center;
	width: 1.75rem;
	height: 1.75rem;
	padding: 0;
	overflow: hidden;
	border-radius: 50%;
	color: var(--color-close-icon);
	background: var(--color-close);
	transition: background-color .15s ease-in-out;
}

.employee-pick:hover {
	background: var(--color-close-hover);
}

.employee-pick svg {
	width: 1rem;
	height: 1rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 2;
	stroke-linecap: round;
}

/* The list of colleagues: a popover like the calendar, drawn like every other menu */
.name-suggest {
	position: fixed;
	max-height: 16rem;
	margin: 0;
	padding: .35rem;
	overflow-y: auto;
	border: 0;
	border-radius: 1rem;
	color: var(--color-text);
	background: var(--color-menu);
	box-shadow: 0 .5rem 1.75rem var(--color-menu-shadow);
}

.name-suggest:popover-open {
	display: grid;
}

.name-suggest-option {
	display: flex;
	align-items: center;
	gap: .6rem;
	padding: .4rem .6rem;
	border-radius: .7rem;
	font-size: .9375rem;
	text-align: left;
	color: var(--color-text);
	transition: background-color .12s ease-in-out;
}

.name-suggest-option:hover,
.name-suggest-option.is-active {
	background: var(--color-menu-hover);
}

.name-suggest-option[aria-selected="true"] {
	font-weight: 600;
}

.name-suggest-text {
	min-width: 0;
}

.name-suggest-text small {
	display: block;
	font-size: .75rem;
	font-weight: 400;
	color: var(--color-text-secondary);
}

/* ---------- Days of an assignment ---------- */
/* The vehicle calendar (.agenda), straight on the sheet of the new-assignment form and
   of an assignment's details — not in a white group (Sep 25): the calendar is white
   itself, and this way it gets the full width of the sheet */
.assignment-days {
	padding: .15rem .1rem .2rem;
}

.assignment-days-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: .5rem;
	margin-bottom: .5rem;
}

.assignment-days-month {
	margin: 0;
	font-size: .8125rem;
	font-weight: 500;
	color: var(--color-text-secondary);
}

.assignment-days-read .assignment-days-month {
	margin-bottom: .45rem;
}

.assignment-days .agenda-interactive .day-cell {
	font-size: .8125rem;
}

/* Today is the darkest fill, exactly as on the vehicle calendar (asked for the
   fill rather than a ring, Sep 23) — chosen or not. The sentence above the calendar
   says whether today is one of the days. */

/* A finger leaves :hover behind on the last day it touched, which looked chosen */
@media (hover: none) {
	.assignment-days .agenda-interactive .day-cell:hover:not(.is-booked):not(.is-today) {
		color: var(--color-text-secondary);
		background: transparent;
	}
}

/* The week numbers get room to breathe: wider column, slightly larger numbers */
.assignment-days .agenda-weeks {
	min-width: 1.9rem;
	padding-inline: .45rem;
}

.assignment-days .agenda-week-number {
	font-size: .625rem;
}

/* "Vandaag" is a word, not an icon: a pill with room either side instead of a circle */
.assignment-days .agenda-nav .agenda-today {
	width: auto;
	padding-inline: .8rem;
	border-radius: 999px;
}

/* Read back in the details sheet: nothing to tap, but big enough to read */
.agenda-read {
	--day-height: 1.75rem;
	--head-height: .95rem;
}

.agenda-read .day-cell {
	font-size: .75rem;
}

.assignment-days-foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: .75rem;
	min-height: 1.75rem;
	margin-top: .45rem;
	font-size: .8125rem;
	color: var(--color-text-secondary);
}

.assignment-days-clear {
	padding: .2rem .55rem;
	border-radius: .5rem;
	font-size: .8125rem;
	font-weight: 600;
	color: var(--color-accent);
}

.assignment-days-clear:hover {
	background: var(--color-fill);
}

/* ---------- Dates (birthday, certificates, inspections, garage log, order date) ---------- */
/* One plain look everywhere (Oct 2, after the forms): a date is a field like a
   text field, "2 oktober 2026" as plain text in it ("dag maand jaar" in grey when
   empty); a tap opens the three wheels. No pills or parts any more. The box is the
   one of the text fields around it: white with a border under a label (like
   .field-input), plain text on the right in a row of a white group (.field-row), and
   inside a white .pfield the field itself is the box (.form-date, further on). */
.date-pill {
	display: flex;
	min-width: 0;
}

/* Under a label: one fixed width everywhere, room for the longest date ("27 september
   2026") and no more (Oct 2); a field with its name inside it and a row of a white
   group size it their own way (further on) */
.date-pill-button {
	display: flex;
	flex: none;
	align-items: center;
	gap: .3em;
	width: 11rem;
	max-width: 100%;
	min-width: 0;
	height: 2.4rem;
	padding: 0 .75rem;
	border: 1px solid var(--color-field-border);
	border-radius: .75rem;
	corner-shape: squircle;
	font: inherit;
	font-size: .9375rem;
	text-align: left;
	color: var(--color-text);
	background: var(--color-field);
	cursor: pointer;
	transition: border-color .15s ease-in-out;
}

/* Lit like a field being typed in while its wheels are open */
.date-pill-button[aria-expanded="true"],
.date-pill-button:focus-visible {
	border-color: var(--color-accent);
	outline: 0;
}

.date-pill-part {
	flex: none;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

.date-pill-part.is-empty {
	color: var(--color-placeholder);
}

/* In a row of a white group (the order date): plain text on the right, like the
   values above and under it */
.field-row .date-pill {
	flex: 1;
	justify-content: flex-end;
}

.field-row .date-pill-button {
	justify-content: flex-end;
	width: auto;
	height: auto;
	padding: 0;
	border: 0;
	border-radius: 0;
	color: var(--color-label-secondary);
	background: none;
}

/* The label on its own line (with the red ! next to it), the pill under it */
.date-pill-field .field-label {
	display: flex;
	align-items: center;
	gap: .4rem;
}

/* The pop-up: three wheels side by side and a round ✓ under them */
.date-wheel {
	--wheel-item: 1.95rem;
	--wheel-rows: 7;
	position: fixed;
	width: min(18rem, calc(100vw - 2rem));
	margin: 0;
	padding: .35rem .35rem .75rem;
	overflow: hidden;
	border: 0;
	border-radius: 1.25rem;
	corner-shape: squircle;
	color: var(--color-text);
	background: var(--color-menu);
	box-shadow: 0 10px 30px var(--color-menu-shadow);
}

.date-wheel:popover-open {
	display: flex;
	flex-direction: column;
	align-items: stretch;
}

.date-wheel-columns {
	position: relative;
	display: grid;
	grid-template-columns: 3.4rem minmax(0, 1fr) 4.4rem;
}

.date-wheel-band {
	position: absolute;
	top: 50%;
	left: .15rem;
	right: .15rem;
	height: var(--wheel-item);
	translate: 0 -50%;
	border-radius: .65rem;
	corner-shape: squircle;
	background: var(--color-fill);
	pointer-events: none;
}

.date-wheel-list {
	position: relative;
	height: calc(var(--wheel-item) * var(--wheel-rows));
	overflow-y: auto;
	overscroll-behavior: contain;
	scroll-snap-type: y mandatory;
	scrollbar-width: none;
	-webkit-mask-image: linear-gradient(#00000000, #000000 16%, #000000 84%, #00000000);
	mask-image: linear-gradient(#00000000, #000000 16%, #000000 84%, #00000000);
}

.date-wheel-list::-webkit-scrollbar {
	display: none;
}

.date-wheel-pad {
	height: calc(var(--wheel-item) * (var(--wheel-rows) - 1) / 2);
}

.date-wheel-item {
	display: block;
	width: 100%;
	height: var(--wheel-item);
	margin: 0;
	padding: 0 .6rem;
	overflow: hidden;
	border: 0;
	font: inherit;
	font-size: .9375rem;
	font-weight: 500;
	line-height: var(--wheel-item);
	font-variant-numeric: tabular-nums;
	text-align: center;
	text-overflow: ellipsis;
	white-space: nowrap;
	scroll-snap-align: center;
	color: var(--color-text-secondary);
	background: none;
	cursor: pointer;
	transition: color .12s ease-in-out;
}

.date-wheel-item.is-centred {
	font-weight: 700;
	color: var(--color-text);
}

/* The ✓ in the middle; "Wissen" small in the corner, only when there is a date */
.date-wheel-foot {
	position: relative;
	display: flex;
	justify-content: center;
	padding-top: .6rem;
}

.date-wheel-done {
	display: grid;
	place-items: center;
	width: 2.9rem;
	height: 2.9rem;
	padding: 0;
	border: 0;
	border-radius: 50%;
	color: var(--color-on-button-primary);
	background: var(--color-button-primary);
	cursor: pointer;
}

.date-wheel-done:hover {
	background: var(--color-button-primary-hover);
}

.date-wheel-done svg {
	width: 1.45rem;
	height: 1.45rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 2.6;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.date-wheel-clear {
	position: absolute;
	left: .45rem;
	bottom: .55rem;
	padding: .3rem .55rem;
	border: 0;
	border-radius: 999px;
	font: inherit;
	font-size: .8125rem;
	font-weight: 500;
	color: var(--color-text-secondary);
	background: none;
	cursor: pointer;
}

.date-wheel-clear:hover {
	background: var(--color-fill);
}

/* ---------- Something to look at (an expiry date that runs out) ---------- */
/* The red ! next to the field in someone's details, and the "Let op" chip in the
   Users list. Both follow the date: fix the date and they are gone. */
.attention-mark {
	display: inline-grid;
	place-items: center;
	flex-shrink: 0;
	width: 1.15rem;
	height: 1.15rem;
	border-radius: 50%;
	font-size: .75rem;
	font-weight: 800;
	line-height: 1;
	color: var(--color-on-attention);
	background: var(--color-attention);
}

.chip-person-attention {
	color: var(--color-on-attention);
	background: var(--color-attention);
}

/* ---------- VCA ---------- */
.vca-state {
	margin: .1rem 0 0;
	font-size: .8125rem;
	font-weight: 600;
}

.vca-state-soon { color: var(--color-soon); }
.vca-state-expired { color: var(--color-expired); }

.vca-state-slot:empty {
	display: none;
}

/* ---------- No connection ---------- */
/* One small card with a no-wifi sign, over everything. Blurred and desaturated
   behind, like every layer in this app, and a little darker than a pop-up's, because
   this one is not something you can close. */
.offline {
	margin: auto;
	padding: 0;
	border: 0;
	background: transparent;
	overflow: visible;
}

.offline[open]::backdrop {
	background: var(--color-offline-backdrop);
	-webkit-backdrop-filter: blur(4px) saturate(.5);
	backdrop-filter: blur(4px) saturate(.5);
}

.offline-card {
	display: grid;
	place-items: center;
	width: 5.5rem;
	height: 5.5rem;
	border-radius: 1.6rem;
	corner-shape: squircle;
	color: var(--color-offline-icon);
	background: var(--color-offline-card);
	box-shadow: 0 .75rem 2rem var(--color-menu-shadow);
}

.offline-card svg {
	width: 2.6rem;
	height: 2.6rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.9;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.offline-card svg circle {
	fill: currentColor;
	stroke: none;
}

@media (prefers-reduced-motion: no-preference) {
	.offline[open] .offline-card {
		animation: offline-pulse 2.4s ease-in-out infinite;
	}
}

@keyframes offline-pulse {
	50% { opacity: .6; }
}

/* ---------- Paper sheets: uurbon + assignment, form and read-back (.sheet-paper) ---------- */
/* One look for the four pop-ups that are "a paper": the uurbon form, a saved uurbon,
   the new-assignment form and an assignment's details (Sep 23). */
/* A little closer to the edges of the screen than the other pop-ups (still a pop-up,
   not full screen), a little less air beside the groups, and groups half as round:
   the call for this form, Sep 23. The saved uurbon (#hours-sheet) gets exactly the
   same frame, so opening one after saving looks like the form it came from. */
/* max-width too: the browser's own style for a modal dialog keeps 2em + 6px free
   on each side, which is wider than the gap asked for here */
.sheet-paper {
	width: min(calc(100% - 1.5rem), 30rem);
	max-width: calc(100% - 1.5rem);
	max-height: calc(100% - 1.5rem);
}

.sheet-paper .settings-inner {
	max-height: calc(100dvh - 1.5rem);
	padding-inline: .6rem;
}

.sheet-paper .settings-head {
	margin-inline: -.6rem;
}

.sheet-paper .settings-group {
	border-radius: .625rem;
}

/* The hours in a row start at the left of their pill, in line with the "Uren"
   heading above them and the total below */
.hours-day .wheelfield-button {
	justify-content: flex-start;
	padding-inline: .6rem .35rem;
}

/* The uurbon and new-assignment forms: less round than the other pop-ups (2rem),
   squircle where the browser draws it; Safari draws plain round corners, which look
   larger at the same number, so it gets a smaller one */
.sheet-paper {
	border-radius: 1.5rem;
	corner-shape: squircle;
}

@supports not (corner-shape: squircle) {
	.sheet-paper {
		border-radius: 1.1rem;
	}
}

/* Groups without a heading of their own still stand apart */
.sheet-paper .settings-group + .settings-group {
	margin-top: .6rem;
}

@supports not (corner-shape: squircle) {
	.card {
		border-radius: .75rem;
	}
}

/* ---------- Uurbon: labels and values (Sep 23) ---------- */
/* In the three groups at the top, the name of a field is medium weight (600 was too
   heavy) and what is typed in it is darker than the usual grey value. */
.sheet-paper .field-row:not(.hours-day) > span:first-child,
.sheet-paper .employee-row > label {
	font-weight: 500;
}

.sheet-paper .field-row > span + input,
.sheet-paper .field-row-text textarea,
.sheet-paper .field-row .op-field input,
.sheet-paper .op-prefix,
.sheet-paper .field-row .employee-field input {
	color: var(--color-uurbon-value);
}

/* The hour and parking fields: a lighter fill than the other controls */
#hours-form .hours-day .wheelfield-button,
#hours-form .hours-parking {
	background: var(--color-hours-field);
}

#hours-form .hours-day .wheelfield-button:hover,
#hours-form .hours-day .wheelfield-button[aria-expanded="true"] {
	background: var(--color-close-hover);
}

/* No empty band under the signatures: the error line only takes room when there is
   an error, and the bottom padding is the same as the sides */
.sheet-paper .form-error:empty {
	display: none;
}

.sheet-paper .settings-inner {
	padding-bottom: .6rem;
}

/* The saved uurbon reads like the form: medium-weight names, darker values */
.sheet-paper .info-row:not(.hours-read) > span:first-child {
	font-weight: 500;
}

.sheet-paper .info-row:not(.hours-read) .row-value {
	color: var(--color-uurbon-value);
}

/* Saved uurbon: the reference and "last saved" under the dates, in the same soft grey */
.sheet-hero .sheet-meta {
	margin: .15rem 0 0;
	font-size: .8125rem;
	color: var(--color-label-secondary);
}

/* The days in a sentence, above the calendar (form and details) */
.assignment-days-summary {
	margin: 0 0 .55rem;
	font-size: .8125rem;
	font-weight: 500;
	line-height: 1.3;
	color: var(--color-uurbon-value);
}

.assignment-days-foot:empty {
	display: none;
}

/* The status pill ends where the typed values end, not past the row's edge */
.sheet-paper .field-row .field-dropdown-compact {
	margin-right: -.1rem;
}

/* ---------- New assignment: status strip ---------- */
/* Not a full-width group: the word on a white tile on the left, the choice on a white
   tile on the right, air in between (roughly 30 / 40 / 30). */
.status-strip {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	margin-bottom: .6rem;
}

.status-strip-label,
.status-strip-dropdown {
	flex: 0 0 auto;
	min-width: 30%;
}

.status-strip-label {
	display: flex;
	align-items: center;
	height: 2.6rem;
	padding: 0 .85rem;
	border-radius: .625rem;
	corner-shape: squircle;
	font-weight: 500;
	color: var(--color-label);
	background: var(--color-group);
}

.status-strip-dropdown .field-dropdown-button {
	height: 2.6rem;
	padding-inline: .85rem .6rem;
	border: 0;
	border-radius: .625rem;
	corner-shape: squircle;
	color: var(--color-uurbon-value);
	background: var(--color-group);
}

.status-strip-dropdown .dropdown-value {
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* The menu is at least as wide as its tile and hangs from its right edge */
.status-strip-dropdown .dropdown-menu {
	left: auto;
	right: 0;
}

/* ---------- New assignment: crew search ---------- */
.crew-search {
	gap: .55rem;
}

.crew-search svg {
	flex-shrink: 0;
	width: 1rem;
	height: 1rem;
	color: var(--color-label-secondary);
}

.sheet-paper .crew-search input {
	text-align: left;
	color: var(--color-uurbon-value);
}

/* The line between the search and the first picked person (they sit in different
   parents, so the usual row + row separator doesn't reach) */
.crew-search + #assignment-form-crew > .crew-person:first-child::before {
	content: "";
	position: absolute;
	top: 0;
	left: .85rem;
	right: .85rem;
	height: 1px;
	background: var(--color-separator);
}

/* Picked people, under the search, each with an × to take them off again */
.crew-person {
	justify-content: space-between;
	min-height: 3rem;
}

.crew-remove {
	display: grid;
	flex-shrink: 0;
	place-items: center;
	width: 1.75rem;
	height: 1.75rem;
	border-radius: 50%;
	color: var(--color-close-icon);
	background: var(--color-close);
	transition: background-color .15s ease-in-out;
}

.crew-remove:hover {
	background: var(--color-close-hover);
}

.crew-remove svg {
	width: .9rem;
	height: .9rem;
	stroke-width: 2.4;
}

.name-suggest-empty {
	margin: 0;
	padding: .55rem .6rem;
	font-size: .875rem;
	color: var(--color-label-secondary);
}

/* ---------- Tapping someone's photo (manage_users only, users.js) ---------- */
/* Tappable avatars look tappable, and sit above a card's invisible tap layer so the
   tap reaches them instead of opening the card */
.can-manage-users [data-person-id] {
	cursor: pointer;
}

.can-manage-users .crew .avatar[data-person-id],
.can-manage-users .person-row .avatar[data-person-id] {
	position: relative;
	z-index: 1;
}

/* The menu: a popover drawn like every other menu in the app */
.person-menu {
	position: fixed;
	min-width: 12rem;
	max-width: min(18rem, calc(100vw - 2rem));
	margin: 0;
	padding: .35rem;
	border: 0;
	border-radius: 1rem;
	color: var(--color-text);
	background: var(--color-menu);
	box-shadow: 0 .5rem 1.75rem var(--color-menu-shadow);
}

.person-menu:popover-open {
	display: grid;
	align-content: start;
	max-height: calc(100dvh - 1rem);
}

/* The name: a label, not an option */
.person-menu-name {
	margin: 0;
	padding: .5rem .8rem .45rem;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-size: .9375rem;
	font-weight: 600;
	border-bottom: 1px solid var(--color-separator);
	margin-bottom: .25rem;
}

.person-menu-item {
	display: flex;
	align-items: center;
	gap: .65rem;
	padding: .55rem .8rem;
	border-radius: .7rem;
	font-size: .9375rem;
	text-align: left;
	color: var(--color-text);
	transition: background-color .12s ease-in-out;
}

.person-menu-item:hover:not(:disabled) {
	background: var(--color-menu-hover);
}

.person-menu-item:disabled {
	color: var(--color-placeholder);
	cursor: default;
}

.person-menu-item svg {
	flex-shrink: 0;
	width: 1.15rem;
	height: 1.15rem;
}

/* ---------- Cards in a week list: only as tall as what is on them ---------- */
/* There used to be a minimum height here (7.4rem, as tall as a fully filled-in
   uurbon). Dropped on Sep 30: on a phone every line of empty card is a card you can't
   see, and more cards on screen beats spotting a missing line by its gap. */

/* ---------- Older weeks, folded under a month or a year ---------- */
.period-group {
	display: flex;
	flex-direction: column;
	gap: 1.1rem;
}

.period-break {
	display: flex;
	align-items: center;
	gap: .55rem;
	width: 100%;
	padding: .5rem .8rem;
	border-radius: .75rem;
	corner-shape: squircle;
	font-size: .875rem;
	font-weight: 600;
	text-align: left;
	color: var(--color-text-secondary);
	background: var(--color-filter-track);
}

.period-break-label::first-letter {
	text-transform: uppercase;
}

.period-break:hover .week-break-arrow {
	color: var(--color-link);
}

.period-group.is-collapsed .period-break .week-break-arrow {
	rotate: -90deg;
}

.period-group.is-collapsed > .period-weeks {
	display: none;
}

.period-weeks {
	display: flex;
	flex-direction: column;
	gap: 1.1rem;
}

/* ---------- Messages (Hub) ---------- */
/* One line of text on a blue or red band. Hold one down (or right-click it) for the
   heart; the deadline and your heart sit on the right. */
/* No wider than a phone and a bit (Sep 25): on a desktop a message stretched across
   the page read oddly. What doesn't fit on one line goes onto the next: the text wraps,
   and the deadline and heart drop to a row of their own, on the right. */
.hub-messages {
	display: grid;
	gap: .5rem;
	max-width: 27rem;
}

.message-line {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	row-gap: .2rem;
	gap: .6rem;
	min-height: 2.75rem;
	padding: .6rem .9rem;
	border-radius: .9rem;
	corner-shape: squircle;
	font-size: .9375rem;
	font-weight: 500;
	line-height: 1.35;
	text-decoration: none;
	-webkit-touch-callout: none;
	-webkit-user-select: none;
	user-select: none;
	transition: scale .18s ease-out, filter .18s ease-out;
}

.message-blue {
	color: var(--color-on-message-blue);
	background: var(--color-message-blue);
}

.message-red {
	color: var(--color-on-message-red);
	background: var(--color-message-red);
}

.message-green {
	color: var(--color-on-message-green);
	background: var(--color-message-green);
}

.message-line[data-message] {
	cursor: default;
}

.message-line.is-pressed {
	scale: .98;
	filter: brightness(.96);
}

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

.message-text {
	flex: 1 1 11rem;
	min-width: 0;
	overflow-wrap: anywhere;
}

.message-icon {
	display: grid;
	flex-shrink: 0;
}

.message-icon svg {
	width: 1.2rem;
	height: 1.2rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.8;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.message-side {
	display: flex;
	flex-shrink: 0;
	margin-left: auto;
	align-items: center;
	gap: .45rem;
	font-size: .75rem;
	font-weight: 600;
	white-space: nowrap;
	opacity: .85;
}

.message-heart {
	display: inline-flex;
	align-items: center;
	gap: .15rem;
}

.message-heart svg {
	width: 1rem;
	height: 1rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.9;
	stroke-linejoin: round;
}

.message-heart.is-mine svg {
	fill: var(--color-message-heart);
	stroke: var(--color-message-heart);
}

.message-heart b {
	font-weight: 700;
}

/* The bubble with the heart, over the line that was held down */
.message-menu {
	position: fixed;
	margin: 0;
	padding: .3rem;
	border: 0;
	border-radius: 999px;
	background: var(--color-menu);
	box-shadow: 0 .5rem 1.75rem var(--color-menu-shadow);
}

.message-like {
	display: grid;
	place-items: center;
	width: 2.75rem;
	height: 2.75rem;
	padding: 0;
	border: 0;
	border-radius: 50%;
	color: var(--color-text-secondary);
	background: none;
	cursor: pointer;
}

.message-like:hover {
	background: var(--color-menu-hover);
}

.message-like svg {
	width: 1.6rem;
	height: 1.6rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.8;
	stroke-linejoin: round;
	transition: scale .2s cubic-bezier(.3, 1.6, .5, 1);
}

.message-like.is-liked {
	color: var(--color-message-heart);
}

.message-like.is-liked svg {
	fill: currentColor;
	scale: 1.15;
}

/* The Assignments page while access is gone: the same red line, above the list */
.week-list > .message-line {
	margin-bottom: 1rem;
}

/* ---------- Hub: uurbonnen and tiles (hub.js, Oct 2) ---------- */
/* Messages, then your uurbonnen, then the tiles. One column on a phone; on a wide
   screen the tiles stand beside the lines instead of under them. */
.hub {
	display: grid;
	grid-template-columns: minmax(0, 1fr);   /* never wider than the panel: the thin rows cut off with … */
	gap: .5rem;
	align-items: start;
}

.hub-main,
.hub-hours,
.hub-messages {
	grid-template-columns: minmax(0, 1fr);
	min-width: 0;
}

.hub-main {
	display: grid;
	gap: .5rem;
	max-width: 27rem;
}

.hub-messages:empty,
.hub-hours:empty,
.hub-tiles:empty {
	display: none;
}

.hub-hours {
	display: grid;
	gap: .5rem;
}

@media (min-width: 56rem) {
	.hub {
		grid-template-columns: minmax(0, 27rem) minmax(0, 22rem);
		column-gap: 1.25rem;
	}
}

/* A message line that is a button (sent back, approved) */
button.message-line {
	width: 100%;
	text-align: left;
	cursor: pointer;
}

button.message-line:active {
	scale: .98;
}

.hub-line-note {
	display: block;
	margin-top: .1rem;
	font-size: .8125rem;
	font-weight: 400;
	line-height: 1.3;
	opacity: .9;
}

/* The pen on a sent-back line: tap to fix it */
.hub-line-action {
	display: grid;
	flex-shrink: 0;
	place-items: center;
	width: 1.9rem;
	height: 1.9rem;
	margin: -.3rem -.45rem -.3rem 0;
	border-radius: 50%;
	background: color-mix(in srgb, currentColor 12%, transparent);
}

.hub-line-action svg {
	width: 1rem;
	height: 1rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 2;
	stroke-linejoin: round;
}

.hub-line .message-text {
	flex-basis: 0;
}

/* A tip (the end-of-week one): the same soft grey as the tiles, never a colour that
   reads as a warning */
.message-tip {
	color: var(--color-text);
	background: var(--color-tile);
}

.message-tip .message-icon {
	color: var(--color-text-secondary);
}

/* Concepts: one extra-thin grey row each, apart from each other with the same gap as
   the lines above and below (Oct 2). The bar on the left is the company's colour, as on
   the cards. */
.hub-papers {
	display: grid;
	gap: .5rem;
}

.hub-paper {
	position: relative;
	display: flex;
	align-items: center;
	min-height: 2.5rem;
	padding: 0 .3rem 0 .75rem;
	border-radius: .9rem;
	corner-shape: squircle;
	background: var(--color-tile);
}

.hub-paper::before {
	content: '';
	position: absolute;
	left: .7rem;
	top: .6rem;
	bottom: .6rem;
	width: 3px;
	border-radius: 2px;
	background: var(--hub-bar, var(--color-mark-draft));
}

.hub-paper-open {
	display: flex;
	flex: 1;
	align-items: baseline;
	gap: .5rem;
	min-width: 0;
	padding: .5rem .4rem .5rem .55rem;
	font-size: .875rem;
	text-align: left;
}

.hub-paper-week {
	font-weight: 700;
	white-space: nowrap;
}

.hub-paper-what {
	flex: 1;
	min-width: 0;
	overflow: hidden;
	color: var(--color-text-secondary);
	text-overflow: ellipsis;
	white-space: nowrap;
}

.hub-paper-hours {
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

.hub-paper-pin {
	display: grid;
	flex-shrink: 0;
	place-items: center;
	width: 1.9rem;
	height: 1.9rem;
	border-radius: 50%;
	color: var(--color-button-primary);
	background: var(--color-tile-item);
}

.hub-paper-pin.is-empty {
	background: none;
}

.hub-paper-pin svg {
	width: 1.05rem;
	height: 1.05rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 2;
	stroke-linejoin: round;
}

/* "+ 2 meer": a row of its own like the concepts */
.hub-papers-more {
	display: block;
	width: 100%;
	padding: .45rem 1.3rem .5rem;
	border-radius: .9rem;
	corner-shape: squircle;
	font-size: .8125rem;
	font-weight: 600;
	text-align: left;
	color: var(--color-accent);
	background: var(--color-tile);
}

/* Tiles: two side by side, a big number and a line under it */
.hub-tiles {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: .5rem;
	max-width: 27rem;
	margin-top: .25rem;
}

@media (min-width: 56rem) {
	.hub-tiles {
		margin-top: 0;
	}
}

.hub-tile {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	min-height: 7.5rem;
	padding: .75rem .85rem .8rem;
	border-radius: 1.15rem;
	corner-shape: squircle;
	color: var(--color-text);
	background: var(--color-tile);
	text-align: left;
	text-decoration: none;
	cursor: pointer;
	-webkit-tap-highlight-color: transparent;
	transition: scale .15s ease-out, background-color .2s ease-in-out;
}

.hub-tile:hover {
	background: color-mix(in srgb, var(--color-tile) 92%, var(--color-text));
}

.hub-tile:active {
	scale: .97;
}

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

.hub-tile-top {
	display: flex;
	width: 100%;
	min-height: 1.75rem;
	margin-bottom: auto;
	align-items: center;
	justify-content: space-between;
}

.hub-tile-icon {
	display: grid;
	place-items: center;
	width: 1.75rem;
	height: 1.75rem;
	border-radius: .55rem;
	color: var(--color-button-primary);
	background: var(--color-tile-item);
}

.hub-tile-icon svg {
	width: 1.1rem;
	height: 1.1rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.9;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.hub-tile-p {
	font-size: .95rem;
	font-weight: 800;
}

.hub-tile-chevron {
	width: 1rem;
	height: 1rem;
	fill: none;
	stroke: var(--color-text-secondary);
	stroke-width: 2.2;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.hub-tile-number {
	margin-top: .6rem;
	font-size: 1.75rem;
	font-weight: 750;
	font-variant-numeric: tabular-nums;
	line-height: 1.1;
	letter-spacing: -.02em;
}

.hub-tile-number.is-word {
	font-size: 1.4rem;
}

.hub-tile-number small {
	font-size: .875rem;
	font-weight: 600;
	letter-spacing: 0;
	color: var(--color-text-secondary);
}

.hub-tile-label {
	margin-top: .1rem;
	font-size: .8125rem;
	font-weight: 500;
	line-height: 1.25;
	color: var(--color-text-secondary);
}

.hub-tile-sub {
	margin-top: .25rem;
	font-size: .75rem;
	line-height: 1.25;
	color: var(--color-text-secondary);
}

/* The countdown keeps one height whichever day off it shows (Oct 2): the number's
   line as high as a number even when it says "Morgen", room for two lines of the day's
   name ("tot Tweede Pinksterdag"), and the date on one line */
.hub-tile-countdown .hub-tile-number {
	min-height: calc(1.75rem * 1.1);
}

.hub-tile-countdown .hub-tile-label {
	display: -webkit-box;
	min-height: 2.5em;
	overflow: hidden;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
	line-clamp: 2;
}

.hub-tile-countdown .hub-tile-sub {
	max-width: 100%;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* A tap shows the next day off: the number, the name and the date glide up into place,
   ease-in-out, the name and date a moment after the number (Oct 2) */
.hub-tile-countdown.is-stepping :is(.hub-tile-number, .hub-tile-label, .hub-tile-sub) {
	animation: hub-countdown-step .32s ease-in-out both;
}

.hub-tile-countdown.is-stepping .hub-tile-label {
	animation-delay: .04s;
}

.hub-tile-countdown.is-stepping .hub-tile-sub {
	animation-delay: .08s;
}

@keyframes hub-countdown-step {
	from {
		opacity: 0;
		translate: 0 .4rem;
	}
	to {
		opacity: 1;
		translate: 0 0;
	}
}

@media (prefers-reduced-motion: reduce) {
	.hub-tile-countdown.is-stepping :is(.hub-tile-number, .hub-tile-label, .hub-tile-sub) {
		animation: none;
	}
}

/* Someone's VCA has already run out: the tile says so in red */
.hub-tile-alert .hub-tile-icon {
	color: var(--color-on-message-red);
	background: var(--color-message-red);
}

.hub-tile-alert .hub-tile-sub {
	font-weight: 600;
	color: var(--color-on-message-red);
}

/* Why an uurbon was sent back, in its details */
.hours-view-note {
	margin: .5rem 0 .75rem;
}

/* ---------- The route pop-up (hub.js) ---------- */
/* The street and place are its title (Oct 2): a long one ends in an ellipsis rather
   than pushing the close button around */
#map-sheet-title {
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* One to one: a square of map, the address in the middle */
.map-frame {
	position: relative;
	aspect-ratio: 1 / 1;
	overflow: hidden;
	border-radius: 1rem;
	corner-shape: squircle;
	background: var(--color-tile);
}

/* Google's map lives in a frame of its own and can't be styled from here. The
   "Openen in Maps" card in its top left corner is cropped off instead (Oct 2): the map
   is drawn taller than the square and pushed up under its top edge. The line at the
   bottom (Google, Kaartgegevens, Voorwaarden) stays in sight: Google's terms ask for it. */
.map-frame iframe {
	position: absolute;
	right: 0;
	bottom: 0;
	left: 0;
	width: 100%;
	height: calc(100% + 4rem);
	border: 0;
}

.map-frame-pin {
	position: absolute;
	inset: 0;
	display: grid;
	place-items: center;
	color: var(--color-text-secondary);
}

.map-frame-pin svg {
	width: 2.5rem;
	height: 2.5rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.6;
}

.map-apps {
	display: grid;
	gap: .5rem;
	margin-top: 1rem;
}

.map-apps .button {
	text-decoration: none;
}

/* ---------- A list limited from the Hub ---------- */
/* "Te beoordelen 3 ×" above the list; the × shows everything again */
.focus-chip-row {
	margin-bottom: .75rem;
}

.focus-chip {
	display: inline-flex;
	align-items: center;
	gap: .4rem;
	padding: .25rem .3rem .25rem .85rem;
	border-radius: 999px;
	font-size: .8125rem;
	font-weight: 600;
	color: var(--color-on-button-primary);
	background: var(--color-button-primary);
}

.focus-chip b {
	opacity: .75;
}

.focus-chip button {
	display: grid;
	place-items: center;
	width: 1.6rem;
	height: 1.6rem;
	border-radius: 50%;
	background: color-mix(in srgb, currentColor 22%, transparent);
}

.focus-chip svg {
	width: .85rem;
	height: .85rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 2.8;
	stroke-linecap: round;
}

/* The reason under "Waarom?" in the Afkeuren pop-up */
.confirm-note {
	display: block;
	width: 100%;
	margin: -.5rem 0 1rem;
	font-size: .9375rem;
	text-align: left;
}

.confirm-note[hidden] {
	display: none;
}

/* ---------- Notifications page ---------- */
/* A little more air between the groups than in a profile: each is a choice */
.notify-compose > .field + .field,
.notify-compose > .notify-preview + .field {
	margin-top: .9rem;
}

.notify-preview:empty {
	display: none;
}

.notify-preview {
	margin-top: .6rem;
}

.notify-tones,
.notify-audiences,
.notify-chips {
	display: flex;
	flex-wrap: wrap;
	gap: .4rem;
}

.notify-tone,
.notify-chip {
	position: relative;
	display: inline-flex;
	cursor: pointer;
}

.notify-tone input,
.notify-chip input {
	position: absolute;
	opacity: 0;
	pointer-events: none;
}

.notify-tone span,
.notify-chip span {
	display: inline-flex;
	align-items: center;
	gap: .4rem;
	min-height: 2.1rem;
	padding: 0 .85rem;
	border: 1px solid var(--color-field-border);
	border-radius: 999px;
	font-size: .875rem;
	font-weight: 500;
	color: var(--color-text);
	background: var(--color-field);
	transition: background-color .12s ease-in-out, border-color .12s ease-in-out;
}

/* A dot in the colour the line will get */
.notify-tone span::before {
	content: "";
	width: .8rem;
	height: .8rem;
	border-radius: 50%;
}

.notify-tone-blue span::before { background: var(--color-on-message-blue); }
.notify-tone-red span::before { background: var(--color-on-message-red); }
.notify-tone-green span::before { background: var(--color-on-message-green); }

.notify-tone input:checked + span,
.notify-chip input:checked + span {
	border-color: var(--color-accent);
	box-shadow: inset 0 0 0 1px var(--color-accent);
	font-weight: 600;
}

.notify-tone input:focus-visible + span,
.notify-chip input:focus-visible + span {
	outline: 2px solid var(--color-accent);
	outline-offset: 2px;
}

.notify-audience-body:not(:empty) {
	margin-top: .6rem;
}

.notify-people-search {
	display: flex;
	align-items: center;
	gap: .5rem;
}

.notify-people-search svg {
	flex-shrink: 0;
	width: 1.05rem;
	height: 1.05rem;
	fill: none;
	stroke: var(--color-text-secondary);
	stroke-width: 2;
	stroke-linecap: round;
}

.notify-people-search input {
	flex: 1;
	min-width: 0;
	height: 100%;
	border: 0;
	outline: 0;
	font: inherit;
	color: inherit;
	background: none;
}

.notify-picked {
	display: flex;
	flex-wrap: wrap;
	gap: .4rem;
}

.notify-picked:not(:empty) {
	margin-top: .5rem;
}

.notify-person {
	display: inline-flex;
	align-items: center;
	gap: .4rem;
	padding: .2rem .2rem .2rem .25rem;
	border-radius: 999px;
	font-size: .875rem;
	font-weight: 500;
	background: var(--color-field);
}

.notify-person button {
	display: grid;
	place-items: center;
	width: 1.6rem;
	height: 1.6rem;
	padding: 0;
	border: 0;
	border-radius: 50%;
	color: var(--color-text-secondary);
	background: none;
	cursor: pointer;
}

.notify-person button:hover {
	background: var(--color-fill);
}

.notify-person svg {
	width: .9rem;
	height: .9rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 2.2;
	stroke-linecap: round;
}

.notify-compose > .button-block {
	margin-top: 1rem;
}

.notify-sent + .notify-sent {
	margin-top: .8rem;
	padding-top: .8rem;
	border-top: 1px solid var(--color-tile-separator);
}

.notify-sent.is-old .message-line {
	opacity: .6;
}

.notify-sent-meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: .15rem .75rem;
	margin-top: .35rem;
	padding-left: .2rem;
	font-size: .75rem;
	font-weight: 500;
	color: var(--color-text-secondary);
}

.notify-delete {
	display: grid;
	place-items: center;
	width: 1.9rem;
	height: 1.9rem;
	margin-left: auto;
	padding: 0;
	border: 0;
	border-radius: 50%;
	color: var(--color-destructive);
	background: none;
	cursor: pointer;
}

.notify-delete:hover {
	background: var(--color-fill);
}

.notify-delete svg {
	width: 1.05rem;
	height: 1.05rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.8;
	stroke-linecap: round;
	stroke-linejoin: round;
}


/* ---------- Saved uurbon: the PDF button at the very bottom, centred (Sep 25) ---------- */
/* Under everything else on the sheet, on the sheet's own background rather than in a
   group: it is something you do with the paper, not a line on it. */
.sheet-export {
	display: flex;
	justify-content: center;
	margin-top: 1rem;
}

.sheet-export .button {
	padding-inline: 1rem 1.1rem;
}

.sheet-export .button svg {
	fill: none;
	stroke: currentColor;
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* The .pdf export buttons: grey like the close × (Sep 28, was an icy blue), so they
   read as a quiet extra next to the blue Save, not as a second main button */
.button-pdf {
	color: var(--color-on-button-pdf);
	background: var(--color-button-pdf);
}

.button-pdf:hover:not(:disabled) {
	background: var(--color-button-pdf-hover);
}

/* ---------- Invoice pop-up (hour-paper-pdf.js) ---------- */
/* Which invoice, week and person, under the title */
.invoice-meta {
	margin: -.2rem 0 .4rem;
	text-align: center;
	font-size: .8125rem;
	color: var(--color-label-secondary);
}

.invoice-meta:empty {
	display: none;
}

/* The date pill sits on the right of its row, like the values above and below it */
.invoice-date-row {
	justify-content: space-between;
}

.invoice-date-row > span {
	font-weight: 500;
}

/* Hourly rate: the € in front of the amount, both on the right */
.invoice-rate {
	flex: 1;
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: .25em;
	min-width: 0;
	color: var(--color-uurbon-value);
}

.invoice-rate input {
	flex: 0 1 auto;
	width: 4.5em;
	field-sizing: content;   /* as wide as the amount, so the € stays right next to it */
	min-width: 2.2em;
	text-align: right;
	color: var(--color-uurbon-value);
}

/* ---------- App-beheer: the company's name (admin.js, Oct 20) ---------- */
.admin-company-fields {
	display: grid;
	gap: .6rem;
}

/* ---------- App-beheer: the login codes (admin.js, Oct 21) ---------- */
/* The example under the letters: "De code wordt bijvoorbeeld ABC-7K4Q-92" */
.admin-login-example {
	margin: .35rem .2rem 0;
	font-size: .8125rem;
	color: var(--color-text-secondary);
	font-variant-numeric: tabular-nums;
}

.admin-login-prefix .field-input {
	text-transform: uppercase;
	letter-spacing: .08em;
}

.admin-login-prefix .field-input::placeholder {
	letter-spacing: normal;
}

/* ---------- App-beheer: company colours (admin.js, Sep 25) ---------- */
/* One block per colour (main colour, banner, navigation bar): a round swatch with the
   native colour picker invisible on top of it, the code, "Standaard", and a row of
   small quick picks under it */
.brand-block + .brand-block {
	margin-top: 1rem;
	padding-top: 1rem;
	border-top: 1px solid var(--color-tile-separator);
}

.brand-picker {
	display: flex;
	align-items: flex-end;
	gap: .65rem;
}

.brand-swatch {
	position: relative;
	flex-shrink: 0;
	width: 2.5rem;
	height: 2.5rem;
	border-radius: 50%;
	background: var(--swatch);
	box-shadow: inset 0 0 0 1px #00000014;
	cursor: pointer;
}

.brand-swatch input {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	margin: 0;
	padding: 0;
	border: 0;
	opacity: 0;
	cursor: pointer;
}

.brand-hex {
	flex: 1;
	min-width: 0;
	max-width: 8.5rem;
}

.brand-hex .field-input {
	font-variant-numeric: tabular-nums;
	letter-spacing: .04em;
	text-transform: uppercase;
}

.brand-picker {
	flex-wrap: wrap;
}

/* Standaard, + and the bin, together; they move to the next line as one on a narrow tile */
.brand-actions {
	display: flex;
	align-items: center;
	gap: .4rem;
}

.brand-reset {
	flex-shrink: 0;
	min-height: 2rem;
	padding-inline: .8rem;
	font-size: .8125rem;
}

/* + (add the current colour to the quick picks) and the bin (remove quick picks) */
.brand-tool {
	display: grid;
	place-items: center;
	width: 2rem;
	height: 2rem;
	border-radius: 50%;
	color: var(--color-on-button-secondary);
	background: var(--color-button-secondary);
	transition: background-color .15s ease-in-out, color .15s ease-in-out;
}

.brand-tool:hover:not(:disabled) {
	background: var(--color-button-secondary-hover);
}

.brand-tool:disabled {
	opacity: .4;
	cursor: default;
}

.brand-tool svg {
	width: 1.05rem;
	height: 1.05rem;
	stroke-width: 2.1;
}

/* The bin pressed: red, and the quick picks turn into things to remove */
.brand-tool-delete.is-active,
.brand-tool-delete.is-active:hover:not(:disabled) {
	color: var(--color-on-button-destructive);
	background: var(--color-button-destructive);
}

.brand-block.is-deleting .brand-preset {
	position: relative;
	animation: brand-wobble .5s ease-in-out infinite alternate;
}

.brand-block.is-deleting .brand-preset::after {
	content: "×";
	position: absolute;
	top: -.35rem;
	right: -.35rem;
	display: grid;
	place-items: center;
	width: .85rem;
	height: .85rem;
	border-radius: 50%;
	font-size: .7rem;
	font-weight: 700;
	line-height: 1;
	color: var(--color-on-button-destructive);
	background: var(--color-button-destructive);
}

@keyframes brand-wobble {
	from { rotate: -4deg; }
	to { rotate: 4deg; }
}

@media (prefers-reduced-motion: reduce) {
	.brand-block.is-deleting .brand-preset {
		animation: none;
	}
}

.brand-hint {
	margin: .5rem 0 0;
	font-size: .8125rem;
	color: var(--color-text-secondary);
}

.brand-presets {
	display: flex;
	flex-wrap: wrap;
	gap: .45rem;
	margin-top: .6rem;
}

.brand-preset {
	width: 1.35rem;
	height: 1.35rem;
	border-radius: 50%;
	background: var(--swatch);
	box-shadow: inset 0 0 0 1px #0000001a;
	transition: scale .15s ease-in-out;
}

.brand-preset:hover {
	scale: 1.1;
}

/* The picked one: a ring in the tile colour, then one in its own colour */
.brand-preset.is-picked {
	box-shadow: 0 0 0 2px var(--color-tile), 0 0 0 3.5px var(--swatch);
}

/* ---------- Nav pinned to the side (desktop, tablet in landscape; Sep 25) ---------- */
/* The pin button next to the nav sets body.nav-pinned (script.js, applyNavPin). Then:
     left column  = the banner in its own white frame on top, the nav below it as a tall
                    panel with every page written out, and the unpin button under the pages
     right column = the page, as wide and tall as what is left
   The three panels share one corner radius (--radius-content). Only where
   html.pin-available is set; turning a tablet upright undoes it without forgetting it. */
.banner-wrap {
	display: contents;
}

.nav-unpin,
.nav-divider {
	display: none;
}

body.nav-pinned {
	/* 21rem, times the width picked by dragging the strip beside it (Oct 21):
	   --pin-scale is .8–1.3, set on <html> by script.js */
	--pin-side: calc(21rem * var(--pin-scale, 1));
	--pin-gap: .6rem;
	/* One radius for the three panels: the banner, the nav and the page. 1.3rem until
	   Oct 5; 1.55rem with the corner shape below, which draws a corner tighter than its
	   number. */
	--radius-content: 1.55rem;
	/* Their corner shape: between a plain round corner (superellipse(1)) and the
	   squircle (superellipse(2)), near round: a softer edge without the squircle look
	   (1.5 and 1.3 looked too sharp, Oct 5). Browsers without corner-shape get a
	   smaller plain radius, below. */
	--corner-content: superellipse(1.2);
	display: grid;
	grid-template-columns: var(--pin-side) minmax(0, 1fr);
	grid-template-rows: minmax(0, 1fr);
	gap: var(--pin-gap);
	padding: var(--pin-gap);
}

/* Browsers without corner-shape (Safari, so every iOS app too) draw plain round corners,
   which look bigger at the same number: a smaller radius looks closest (Oct 5) */
@supports not (corner-shape: superellipse(1.2)) {
	body.nav-pinned {
		--radius-content: 1.4rem;
	}
}

body.nav-pinned .top {
	grid-column: 1;
	grid-row: 1;
	width: auto;
	min-height: 0;
	margin: 0;
	padding: 0;
	align-items: stretch;
	gap: var(--pin-gap);
	background: none;
	border-radius: 0;
}

/* No white frame around the banner here (Sep 25): the banner itself takes the frame's
   place — the full width of the column and the panels' radius — with everything in it
   a size up, so it is about as tall as banner + frame were */
body.nav-pinned .banner-wrap {
	display: block;
	flex-shrink: 0;
}

body.nav-pinned .banner {
	--banner-avatar: 2.1rem;
	--banner-pad-y: .85rem;
	--banner-gap-y: .55rem;
	--banner-inset: .5rem;
	--banner-radius: var(--radius-content);
	width: 100%;
	padding-left: 1.35rem;
	corner-shape: var(--corner-content);
}

body.nav-pinned .banner-user {
	font-size: 1.05rem;
}

body.nav-pinned .banner .avatar {
	font-size: .75rem;
}

body.nav-pinned .banner-date {
	font-size: .875rem;
}

/* The current page: a touch softer than white on the tall panel */
body.nav-pinned .nav-indicator {
	background: var(--color-nav-active-pinned);
}

body.nav-pinned .nav-wrap {
	flex: 1;
	min-height: 0;
	height: auto;
	margin: 0;
}

body.nav-pinned .nav-stack {
	position: static;
	height: 100%;
	align-items: stretch;
}

body.nav-pinned .nav-row {
	height: 100%;
	max-width: none;
	display: block;
}

body.nav-pinned .nav {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: .5rem;
	width: 100%;
	height: 100%;
	padding: .6rem;
	overflow-y: auto;
	border-radius: var(--radius-content);
	corner-shape: var(--corner-content);
}

body.nav-pinned .nav ul {
	align-self: stretch;
	grid-template-columns: minmax(0, 1fr);
}

/* A line across the panel under the pages, with the unpin button under it */
body.nav-pinned .nav-divider {
	display: block;
	align-self: stretch;
	height: 2px;
	margin: .1rem 0;
	border-radius: 1px;
	background: var(--color-nav-divider);
}

body.nav-pinned .nav a {
	padding-left: .75rem;
}

/* The top page sits in the panel's top corners: its corners follow the panel's (its
   radius less the .6rem padding, and a touch less again since the panel's corner shape
   draws tighter than its number, Oct 5), and so does the white pill when it is on it */
body.nav-pinned .nav li:first-child a,
body.nav-pinned .nav-indicator.on-first {
	border-radius: calc(var(--radius-content) - .7rem);
}

body.nav-pinned .nav-indicator {
	transition: transform .38s cubic-bezier(.3, .8, .25, 1), width .38s cubic-bezier(.3, .8, .25, 1),
		opacity .2s ease-in-out, border-radius .38s cubic-bezier(.3, .8, .25, 1);
}

body.nav-pinned .nav .label {
	opacity: 1;
}

body.nav-pinned .nav-side,
body.nav-pinned .nav-tab {
	display: none;
}

/* Unpin: a round button under the list of pages, lined up with the icons */
/* The round button is centred on the icon column (the page links' icons sit .75rem in
   and are 1.2rem wide), and its word starts where the page names start (.75 + 1.2 + .7
   rem), a shade softer than they are so it reads as something else (Sep 25) */
body.nav-pinned .nav-unpin {
	display: flex;
	align-items: center;
	gap: calc(.75rem + 1.2rem + .7rem - (.75rem + .6rem + var(--nav-button) / 2));
	flex-shrink: 0;
	margin-left: calc(.75rem + .6rem - var(--nav-button) / 2);
	font-size: .9rem;
	font-weight: 500;
	letter-spacing: -.01em;
	color: var(--color-nav-item-icon);
}

body.nav-pinned .nav-unpin-icon {
	display: grid;
	place-items: center;
	width: var(--nav-button);
	height: var(--nav-button);
	border-radius: 50%;
	background: var(--color-nav-item-hover);
	transition: color .15s ease-in-out, background-color .15s ease-in-out;
}

body.nav-pinned .nav-unpin:hover {
	color: var(--color-nav-item-text);
}

body.nav-pinned .nav-unpin:hover .nav-unpin-icon {
	background: var(--color-nav-item-press);
}

body.nav-pinned .nav-unpin svg {
	width: 1.1rem;
	height: 1.1rem;
}

body.nav-pinned .content {
	grid-column: 2;
	grid-row: 1;
	padding: 0;
}

body.nav-pinned .content-inner {
	max-width: none;
}

body.nav-pinned .page {
	corner-shape: var(--corner-content);
}

/* The strip in the gap between the nav and the page (Oct 21): drag it sideways to make
   the nav narrower or wider (script.js). It is exactly the gap, so it covers nothing.
   A small grip shows in its middle under the mouse, with the keyboard, and while
   dragging. Not there at all unless the nav is pinned. */
.pin-resizer {
	display: none;
}

body.nav-pinned .pin-resizer {
	display: block;
	position: fixed;
	z-index: 5;
	top: var(--pin-gap);
	bottom: var(--pin-gap);
	left: calc(var(--pin-gap) + var(--pin-side));
	width: var(--pin-gap);
	cursor: col-resize;
	touch-action: none;   /* a finger drags the strip instead of scrolling the page */
	outline: none;
}

body.nav-pinned .pin-resizer::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: 4px;
	height: 2.5rem;
	translate: -50% -50%;
	border-radius: 999px;
	background: var(--color-pin-resizer);
	opacity: 0;
	transition: opacity .15s ease-in-out;
}

body.nav-pinned .pin-resizer:hover::after,
body.nav-pinned .pin-resizer:focus-visible::after,
.pin-resizing body.nav-pinned .pin-resizer::after {
	opacity: 1;
}

/* While dragging: the resize cursor everywhere (the pointer runs ahead of the strip
   onto the nav and the page, whose buttons have their own cursor) and no text gets
   selected along the way */
.pin-resizing,
.pin-resizing * {
	cursor: col-resize !important;
	user-select: none;
}

/* Pinning and unpinning: the banner, the nav and the page glide to their new places
   (View Transitions, like the theme switch; script.js adds the class for the moment) */
.pin-switching .banner { view-transition-name: pin-banner; }
.pin-switching .nav { view-transition-name: pin-nav; }
.pin-switching .page:not([hidden]) { view-transition-name: pin-page; }

::view-transition-group(pin-banner),
::view-transition-group(pin-nav),
::view-transition-group(pin-page) {
	animation-duration: .35s;
	animation-timing-function: cubic-bezier(.3, .8, .25, 1);
}

/* ---------- Phone held sideways (Sep 25) ---------- */
/* The same card as "no connection", with a phone and a turning arrow and one line */
.rotate .offline-card {
	width: auto;
	height: auto;
	gap: .7rem;
	padding: 1.3rem 1.5rem 1.1rem;
}

.rotate .offline-card svg {
	width: 2.6rem;
	height: 2.6rem;
}

.rotate-text {
	font-size: .9375rem;
	font-weight: 600;
	color: var(--color-offline-icon);
}

/* No pulsing here: this card waits for the phone, not for a connection */
.rotate[open] .offline-card {
	animation: none;
}

/* ---------- Cards straight on the page (Vehicles, Users; Sep 25) ---------- */
/* The panel around the list ("Alle 4") is gone: the cards stand on the white page
   under the filters, like the assignments, in the card grey so they still read as
   cards. A little room above them, where the panel's title used to be. */
#vehicle-list,
#user-list {
	margin-top: .15rem;
}

#vehicle-list .vehicle-card,
#user-list .person-row {
	background: var(--color-card);
}

#vehicle-list .vehicle-card:hover,
#user-list .person-row:hover {
	background: var(--color-card-hover);
}

/* ---------- Users list: two lines per person (Sep 28) ---------- */
/* Phone (a card):
     photo | name  [status] [geen login] ............ [3 rechten]
           | functie ............................. 1 aandachtspunt
   Top line solid black 500, bottom line #222 400 (dark theme: light greys). */
#user-list .user-row {
	gap: .75rem;   /* photo and name a little apart (Sep 29, was .55rem) */
	padding: .3rem .6rem .3rem .4rem;
}

#user-list .user-row .avatar-medium {
	width: 2.1rem;
	height: 2.1rem;
	font-size: .72rem;
}

/* A pinned person (Oct 21, avatar menu → Vastpinnen): a red ring on the photo. Drawn
   inside its edge, because the wide list scrolls sideways and would cut off a ring
   outside the first column. */
#user-list .user-row .avatar.is-pinned {
	outline: 2px solid var(--color-user-pinned);
	outline-offset: -2px;
}

.user-row .person-row-main {
	display: grid;
	gap: .1rem;
}

.user-row-line {
	display: flex;
	align-items: center;
	gap: .35rem;
	min-width: 0;
}

.user-row .person-row-name {
	flex: 0 1 auto;
	min-width: 0;
	font-weight: 500;
	line-height: 1.25;
	color: var(--color-user-row-top);
}

.user-row .person-row-sub {
	flex: 1 1 auto;
	min-width: 0;
	font-size: .75rem;
	font-weight: 400;
	line-height: 1.25;
	color: var(--color-user-row-bottom);
}

.user-row .person-row-chips {
	flex: none;
	flex-wrap: nowrap;
	margin-top: 0;
}

.user-row .user-row-rights,
.user-row .person-row-summary {
	flex: none;
	margin-left: auto;
}

.user-row .person-row-summary {
	white-space: nowrap;
	font-size: .7rem;
	line-height: 1.25;
	color: var(--color-user-summary);
}

/* No onderaannemer: the line stays, empty (Oct 20), so the name keeps its place on top
   and the summary stays bottom right */
.user-row .person-row-sub.is-empty {
	visibility: hidden;
}

.user-row .person-cells {
	display: none;
}

/* The header row with the columns' names is for wide screens only (below) */
.user-head {
	display: none;
}

.user-check {
	display: inline-grid;
	place-items: center;
	width: .95rem;
	height: .95rem;
	color: var(--color-user-check-warn);
}

.user-check svg {
	width: .95rem;
	height: .95rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 2.2;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.user-check-ok { color: var(--color-user-check-ok); }
.user-check-warn { color: var(--color-user-check-warn); }
.user-check-bad { color: var(--color-user-check-bad); }
.user-check-extra,
.user-check-extraExpired { color: var(--color-user-check-extra); }

/* Every "–" in the list (nothing there, or a check that doesn't apply): the same grey as
   the ✓ for certificates nobody asked for (Oct 20) */
.user-empty,
.user-check-na { color: var(--color-user-check-extra); }

/* Wider than tall (1:1 and up): one row per person, ONE line, thirteen columns.
   1: photo · 2: name · 3: rechten · 4: onderaannemer · 5: functie · 6: status ·
   7: persoonsgegevens · 8: bedrijfsgegevens · 9: ZZP-code · 10: certificaten (vereist) ·
   11: VCA verloopdatum · 12: uurtarief · 13: voertuig (the order of Oct 20).
   The columns' names are in the header row above the list only (Oct 20): each row
   used to repeat them above its values, which made every row two lines high.
   The photo stands left of the grey row, not in it, as tall as the row itself.
   The columns are shared by every row (subgrid) and each is as wide as its longest
   word, with the same space between all of them — so "VCA" doesn't get as much room
   as "Bedrijfsgegevens". The last, empty track takes what is left on the right, up to 4rem. */
@media (min-aspect-ratio: 1/1) and (min-width: 48rem) {
	/* A screen too narrow for all the columns (or zoomed in): the list scrolls sideways
	   rather than cutting the last ones off (Oct 20). Since Oct 21 it fills the rest of
	   the page and scrolls itself, up and down too, so its sideways bar sits at the
	   bottom of the page instead of right under the last person. The search and the
	   filters stay put above it. */
	.page[data-page="users"] .panel-body {
		display: flex;
		flex-direction: column;
	}

	.page[data-page="users"] .panel-body > .toolbar {
		flex: none;
	}

	#user-list {
		--user-scrollbar: 6px;
		flex: 1 1 auto;
		min-height: 0;
		overflow: auto;
		overscroll-behavior: contain;
		scrollbar-width: auto;   /* undo "No visible scrollbars" here, or Chrome ignores the look below */
		/* A fade on the right while columns are hidden there (Oct 23). users.js sets
		   --user-hidden-right to how far is still hidden; the fade is that wide, 4rem at
		   most, so it shrinks as you scroll and is gone at the far right: it never covers
		   the last column once you are there. It fades the list to transparent, so the
		   page's own colour shows (dark mode too). The second layer keeps the scrollbar
		   along the bottom out of it. */
		--user-fade: min(4rem, var(--user-hidden-right, 0px));
		mask-image:
			linear-gradient(to right, #000 calc(100% - var(--user-fade)), transparent),
			linear-gradient(#000, #000);
		mask-size: 100% calc(100% - var(--user-scrollbar)), 100% var(--user-scrollbar);
		mask-position: top, bottom;
		mask-repeat: no-repeat;
	}

	/* The bar itself, only there while the list is wider than the page: thin, round,
	   two soft greys, nothing else. No bar up the side (width 0); the list still
	   scrolls up and down with the wheel as before. */
	#user-list::-webkit-scrollbar {
		display: block;
		width: 0;
		height: 6px;   /* the same as --user-scrollbar on #user-list */
	}

	#user-list::-webkit-scrollbar-track {
		border-radius: 999px;
		background: var(--color-scroll-track);
	}

	#user-list::-webkit-scrollbar-thumb {
		border-radius: 999px;
		background: var(--color-scroll-thumb);
	}

	#user-list::-webkit-scrollbar-corner {
		background: transparent;
	}

	/* Firefox has no ::-webkit-scrollbar: its own thin bar in the same two colours */
	@supports not selector(::-webkit-scrollbar) {
		#user-list {
			scrollbar-width: thin;
			scrollbar-color: var(--color-scroll-thumb) var(--color-scroll-track);
		}
	}

	#user-list .people {
		--user-col-gap: clamp(1rem, 2.2vw, 2rem);
		--user-avatar: 1.65rem;   /* the photo, and with it the height of a row */
		/* The empty last track grows to 4rem at most (Oct 21): with 1fr it took all the
		   room left, so on a wide (or zoomed-out) screen the rows and the Voertuig fill
		   ran on to the far edge of the page */
		grid-template-columns: var(--user-avatar) minmax(7rem, max-content) repeat(11, max-content) minmax(0, 4rem);
		column-gap: var(--user-col-gap);
		row-gap: .25rem;
	}

	/* The row itself has no background: the grey card is drawn behind it by ::before,
	   starting just right of the photo, so the photo sits outside it */
	#user-list .user-row {
		position: relative;
		isolation: isolate;
		grid-column: 1 / -1;
		display: grid;
		grid-template-columns: subgrid;
		gap: normal;   /* the list's column gap, not the card's */
		align-items: center;
		min-height: var(--user-avatar);
		padding: 0 .75rem 0 0;
		background: none;
	}

	#user-list .user-row:hover {
		background: none;
	}

	#user-list .user-row::before {
		content: "";
		position: absolute;
		z-index: -1;
		inset: 0 0 0 calc(var(--user-avatar) + .4rem);
		border-radius: .55rem;   /* sharper than the row's own (a pill at this height), Oct 20 */
		corner-shape: squircle;
		background: var(--color-user-row);
		transition: background-color .15s ease-in-out;
	}

	#user-list .user-row:hover::before {
		background: var(--color-card-hover);
	}

	#user-list .user-row .avatar-medium {
		width: var(--user-avatar);
		height: var(--user-avatar);
		font-size: .55rem;
	}

	/* One line: the onderaannemer has its own column now, the summary isn't shown here */
	.user-row .user-row-bottom {
		display: none;
	}

	/* A long company name ends in … rather than making the column very wide */
	.person-cell-subcontractor {
		max-width: 12rem;
	}

	/* Name close to the photo, not a whole column gap away — but not touching it either:
	   about .75rem of room (Sep 29; with .55rem here only ~2px was left) */
	.user-row .person-row-main {
		margin-left: calc(1.15rem - var(--user-col-gap));
		gap: 0;
	}

	.user-row .person-row-name {
		font-size: .8rem;
	}

	.user-row .person-row-chips,
	.user-row .user-row-rights,
	.user-row .person-row-summary {
		display: none;
	}

	.user-row .person-cells {
		display: contents;
	}

	.person-cell {
		position: relative;
		display: grid;
		min-width: 0;
	}

	/* A thin stripe in the page's colour between two columns (Oct 21), so the eye keeps
	   to its column along a row. In the middle of the gap left of every column after the
	   name; none between the photo and the name, which already stand apart. */
	#user-list .person-cell::before {
		content: "";
		position: absolute;
		top: 50%;
		left: calc(var(--user-col-gap) / -2);
		width: 3px;
		height: calc(var(--user-avatar) * .7);
		translate: -50% -50%;
		border-radius: 999px;
		background: var(--color-user-col-separator);
	}

	.person-cell-label,
	.person-cell-value {
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
		line-height: 1.25;
	}

	/* The header row says what each column is (Oct 20) */
	.person-cell-label {
		display: none;
	}

	.person-cell-value {
		display: flex;
		align-items: center;
		min-height: 1.125rem;
		font-size: .75rem;
		font-weight: 400;
		font-variant-numeric: tabular-nums;
		color: var(--color-user-row-bottom);
	}

	/* The header row (Oct 20): the columns' names above the first person, in the same
	   grid and with the same padding as a row, so each name is right above its column.
	   A tap orders the list by that column (users.js). Every name has its arrow; only
	   the colour says which column the list is ordered by. */
	#user-list .user-head {
		grid-column: 1 / -1;
		display: grid;
		grid-template-columns: subgrid;
		align-items: stretch;
		padding: 0 .75rem 0 0;
	}

	/* Each name on a light fill of its own, with the rows' corners. A fill is as wide as
	   its column plus the gaps beside it, minus --head-space: the same room as between
	   two rows (the list's row-gap), so the fills sit apart exactly like the rows do.
	   That reach is padding taken back by a negative margin of the same size: the name
	   stays right above its column and the column doesn't get wider for it. */
	.user-head-cell {
		--head-space: .25rem;
		--head-reach: calc((var(--user-col-gap) - var(--head-space)) / 2);
		display: flex;
		align-items: center;
		gap: .2rem;
		justify-self: stretch;
		min-width: 0;
		min-height: var(--user-avatar);   /* as high as a person's row (Oct 20) */
		margin: 0 calc(-1 * var(--head-reach));
		padding: 0 var(--head-reach);
		border: 0;
		border-radius: .55rem;
		corner-shape: squircle;
		font: inherit;
		font-size: .7rem;
		font-weight: 500;
		line-height: 1.25;
		white-space: nowrap;
		text-align: left;
		color: var(--color-on-user-head);
		background: var(--color-user-head);   /* soft blue, so the names stand apart from the grey rows (Oct 21) */
		cursor: pointer;
		transition: color .15s ease-in-out, background-color .15s ease-in-out;
	}

	.user-head-cell:hover,
	.user-head-cell.is-active {
		color: var(--color-on-user-head-active);
	}

	/* The column the list is ordered by also gets a deeper fill, so it shows at a glance */
	.user-head-cell.is-active {
		background: var(--color-user-head-active);
	}

	/* "Vastgepind" (Oct 21), above the photos: a pin instead of the word, since the
	   column is only a photo wide. Its fill is exactly the photo's width, no reach. */
	.user-head-pin {
		justify-content: center;
		margin: 0;
		padding: 0;
	}

	.user-head-pin svg {
		width: .85rem;
		height: .85rem;
		fill: none;
		stroke: currentColor;
		stroke-width: 2;
		stroke-linecap: round;
		stroke-linejoin: round;
	}

	/* "Naam": its fill starts where a row's grey starts (just past the photo) and its
	   text where the names start */
	.user-head-cell[data-user-sort="name"] {
		margin-left: calc(.4rem - var(--user-col-gap));
		padding-left: .75rem;
	}

	/* The last one runs on to the end of the rows, over the empty track after it */
	.user-head-cell:last-child {
		grid-column: -3 / -1;   /* its own column and the empty track after it */
		margin-right: -.75rem;
	}

	.user-head-arrow {
		flex-shrink: 0;
		width: .75rem;
		height: .75rem;
		fill: none;
		stroke: currentColor;
		stroke-width: 2.4;
		stroke-linecap: round;
		stroke-linejoin: round;
		transition: rotate .2s ease-in-out;
	}

	.user-head-cell.is-reversed .user-head-arrow {
		rotate: 180deg;
	}

	/* VCA verloopdatum: amber when it runs out soon, red once it has */
	.user-vca-soon { color: var(--color-soon); }
	.user-vca-expired { color: var(--color-expired); }
}

/* ---------- Vehicle pop-up photo (Sep 25) ---------- */
/* A square, a bit smaller than the old wide box, with its two buttons beside it at the
   bottom right instead of on its corners: the camera at the very bottom, the bin
   (only while there is a photo) above it. An empty column of the same width on the
   left keeps the photo itself in the middle. */
.vehicle-photo-wrap {
	display: inline-grid;
	grid-template-columns: 1.9rem auto 1.9rem;
	grid-template-rows: 1fr auto auto;
	column-gap: .45rem;
	row-gap: .4rem;
	align-items: end;
}

.vehicle-photo-wrap .vehicle-photo-button {
	grid-column: 2;
	grid-row: 1 / 4;
}

.vehicle-photo-wrap .avatar-badge {
	position: static;
	grid-column: 3;
	grid-row: 3;
}

.vehicle-photo-wrap .avatar-badge-remove {
	grid-row: 2;
}

.vehicle-photo-large {
	width: 8.5rem;
	height: 8.5rem;
	aspect-ratio: 1;
}

/* ---------- App-beheer: tidier colour rows (Sep 25) ---------- */
/* The code field was squeezed to nothing next to the buttons: it keeps a minimum width,
   is lower and less round, and Standaard is a round icon like + and the bin. All three
   are drawn in the same colour, also when they can't be used right now. */
.brand-hex {
	flex: 1 1 6.5rem;
	min-width: 6.5rem;
	max-width: 8.5rem;
}

.brand-hex .field-label {
	margin-bottom: .1rem;
	line-height: 1rem;
}

.brand-hex .field-input {
	height: 2rem;
	padding: 0 .55rem;
	border-radius: .5rem;
	font-size: .875rem;
	line-height: 2rem;
}

.brand-swatch {
	width: 2.25rem;
	height: 2.25rem;
}

.brand-tool:disabled {
	opacity: 1;
	cursor: default;
}

/* ---------- Uurbon and invoice: an A4 sheet where there is room (Sep 25) ---------- */
/* On a phone these pop-ups stay phone-sized. On a computer or tablet (either way up)
   they take the full height they have and the width that goes with it on A4
   (height / √2), so the uurbon looks like the paper it replaces. Still scrolls. */
@media (min-width: 40rem) and (min-height: 32rem) {
	#hours-form-sheet,
	#hours-sheet,
	#invoice-sheet {
		--a4-height: calc(100dvh - 1.5rem);
		height: var(--a4-height);
		width: min(calc(100% - 1.5rem), calc(var(--a4-height) / 1.4142));
		max-width: calc(100% - 1.5rem);
	}

	#hours-form-sheet .settings-inner,
	#hours-sheet .settings-inner,
	#invoice-sheet .settings-inner {
		height: 100%;
		max-height: 100%;
	}

	/* Room for the two signatures next to each other */
	:is(#hours-form, #hours-sheet) .settings-group:has(.signature) {
		display: grid;
		grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	}

	:is(#hours-form, #hours-sheet) .signature + .signature::before {
		top: .85rem;
		bottom: .85rem;
		left: 0;
		right: auto;
		width: 1px;
		height: auto;
	}
}

/* A signature pad keeps the shape of its picture (900 × 390) at every width, so a
   signature is never stretched when the sheet is wider */
.signature-pad {
	height: auto;
	aspect-ratio: 900 / 390;
}

/* ".pdf" in the header of a saved uurbon, next to the round edit and copy buttons */
.sheet-pdf {
	min-height: 1.9rem;
	padding-inline: .75rem;
	font-size: .8125rem;
}

/* ---------- Bedrijven page (companies.js, Sep 25) ---------- */
/* A card like a person on the Users page: a square with the initials instead of a
   photo, the short name ("ABC") and the company name ("ABC B.V."), and the switch that
   says whether it can be picked on an invoice (above the card's tap layer). */
.company-badge {
	flex-shrink: 0;
	display: grid;
	place-items: center;
	width: 3.3rem;
	height: 2.6rem;
	border-radius: .7rem;
	corner-shape: squircle;
	font-size: .8125rem;
	font-weight: 700;
	letter-spacing: .04em;
	color: var(--color-avatar-text);
	background: var(--color-avatar);
}

.company-badge-small {
	width: 2.4rem;
	height: 1.9rem;
	border-radius: .5rem;
	font-size: .625rem;
	letter-spacing: .02em;
}

.company-toggle {
	position: relative;
	z-index: 1;
	flex-shrink: 0;
	align-self: flex-end;          /* bottom right of the card (Sep 25), as far from the */
	margin-bottom: .35rem;         /* bottom as from the right: .4 + .35 = the .75rem side */
	display: flex;
	align-items: center;
}

/* Your own company's card (everyone without manage_companies, Sep 28): a quiet
   "Jouw bedrijf" where the office has its switch */
.company-own-label {
	flex-shrink: 0;
	align-self: flex-end;
	margin-bottom: .35rem;
	font-size: .7rem;
	color: var(--color-text-secondary);
}

/* "Via mijn bedrijf" in an assignment's details, with the company's name under it */
.company-member-row > span {
	display: grid;
	gap: .1rem;
	min-width: 0;
}

.company-member-row small {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-size: .75rem;
	color: var(--color-text-secondary);
}

a.sheet-action[data-company-member-add] {
	text-decoration: none;
}

/* The switch on a card is 60% of the usual one (Sep 25) */
.company-toggle .switch {
	width: 2.4rem;
	height: 1.05rem;
	border-radius: .6rem;
}

.company-toggle .switch::before {
	top: .125rem;
	left: .125rem;
	width: 1.3rem;
	height: .8rem;
	border-radius: .4rem;
}

.company-toggle .switch:checked::before {
	translate: .85rem 0;
}

/* On: a plain #485D70 of its own rather than the main colour (Sep 30), so the switches don't compete
   with the companies' own colours on the cards */
.company-toggle .switch:checked {
	background: var(--color-switch-company);
}

/* The badge sits as far from the card's left edge as from its top and bottom */
#company-list .person-row {
	padding: .4rem .75rem .4rem .4rem;
}

#company-list .person-row {
	background: var(--color-card);
}

#company-list .person-row:hover {
	background: var(--color-card-hover);
}

#company-list {
	margin-top: .15rem;
}

/* ---------- Invoice pop-up: the company pickers (Sep 25) ---------- */
/* "Bedrijf" on the left, the chosen company on the right with an arrow to open the
   list; typing narrows it down, like picking a colleague on an uurbon */
.company-pick-row {
	gap: .75rem;
}

.company-field {
	flex: 1;
	min-width: 0;
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: .35rem;
}

.company-field .company-input {
	flex: 1;
	min-width: 0;
	text-align: right;
	font-weight: 500;
	color: var(--color-uurbon-value);
}

.company-arrow {
	flex-shrink: 0;
	display: grid;
	place-items: center;
	width: 1.9rem;
	height: 1.9rem;
	border-radius: 50%;
	color: var(--color-label-secondary);
	background: var(--color-fill);
	transition: background-color .15s ease-in-out;
}

.company-arrow:hover {
	background: var(--color-close-hover);
}

.company-arrow svg {
	width: 1rem;
	height: 1rem;
	stroke-width: 2.4;
	transition: rotate .2s ease-in-out;
}

.company-field.is-open .company-arrow svg {
	rotate: 180deg;
}

/* What will be on the invoice, under the picker: read-only, a size smaller */
.company-info {
	position: relative;
	display: grid;
	gap: .1rem;
	padding: .55rem 1rem .7rem;
	font-size: .8125rem;
	line-height: 1.15rem;
	color: var(--color-text-secondary);
	background: var(--color-group);
}

.company-info::before {
	content: "";
	position: absolute;
	top: 0;
	left: 1rem;
	right: 0;
	height: 1px;
	background: var(--color-separator);
}

.company-info-empty {
	margin: 0;
	font-style: italic;
}

.company-suggest-empty {
	margin: 0;
	padding: .75rem 1rem;
	font-size: .875rem;
	color: var(--color-text-secondary);
}

/* ---------- A round bin in a pop-up's header (Sep 25) ---------- */
/* Next to Opslaan, the same height, grey with a dark grey bin (Sep 28, was red): small,
   so it doesn't compete with saving, and it still asks before anything goes (askConfirm). */
.head-delete {
	display: grid;
	place-items: center;
	width: 2.1rem;
	height: 2.1rem;
	border-radius: 50%;
	color: var(--color-delete-soft-icon);
	background: var(--color-delete-soft);
	transition: background-color .15s ease-in-out;
}

.head-delete:hover {
	background: var(--color-delete-soft-hover);
}


.head-delete svg {
	width: 1.05rem;
	height: 1.05rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 2;
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* ---------- User page and a person's pop-up: tighter fields (Sep 25) ---------- */
/* The name small above the field, lower fields with no outline (the accent one still
   shows while typing), every field on its own row, and each only about as wide as what
   goes in it rather than the full width of the tile. The sizes sit close together. (A
   try with every tile as one white table was dropped: boxes inside boxes.) */
:is(#profile-form, #person-form, #formpage-form) .field + .field,
:is(#profile-form, #person-form, #formpage-form) .field + .field-pair,
:is(#profile-form, #person-form, #formpage-form) .field-pair + .field,
:is(#profile-form, #person-form, #formpage-form) .field-pair + .field-pair {
	margin-top: .5rem;
}

:is(#profile-form, #person-form, #formpage-form) .field-pair > .field {
	margin-top: 0;
}

:is(#profile-form, #person-form, #formpage-form) .field-label {
	margin: 0 0 .1rem .1rem;
	font-size: .75rem;
	line-height: 1rem;
}

:is(#profile-form, #person-form, #formpage-form) .field-input,
:is(#profile-form, #person-form, #formpage-form) .field-dropdown-button {
	height: 2.1rem;
	border-color: transparent;
	border-radius: .65rem;
	font-size: .9rem;
}

:is(#profile-form, #person-form, #formpage-form) .field-input:focus {
	border-color: var(--color-accent);
}

:is(#profile-form, #person-form, #formpage-form) .field-input,
:is(#profile-form, #person-form, #formpage-form) .field-dropdown {
	max-width: 17rem;
}

/* Short things get short fields. The country is as wide as street, postcode and city
   above it (Sep 28, "Nederland" written out). */
:is(#profile-form, #person-form, #formpage-form) .field-input[name="shoe_size"] {
	max-width: 3.6rem;
}

:is(#profile-form, #person-form, #formpage-form) .field-input:is([name="phone"]) {
	max-width: 10rem;
}

:is(#profile-form, #person-form, #formpage-form) .date-pill-field .field-label {
	margin-bottom: .1rem;
}

/* ---------- The client's order on an assignment (assignment-order.js, Sep 25) ---------- */
/* The orderbon row in the Order pop-up: its name (tap to look at it) with Vervangen and
   × on the right, or "Nog geen orderbon" with Toevoegen */
.order-file-row {
	gap: .6rem;
	padding-block: .45rem;
}

.order-file-name {
	flex: 1;
	min-width: 0;
	display: flex;
	align-items: center;
	gap: .45rem;
	text-align: left;
	color: var(--color-link);
}

.order-file-name span {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.order-file-name svg,
.sheet-action svg {
	flex-shrink: 0;
}

.order-file-name svg {
	width: 1.1rem;
	height: 1.1rem;
}

.order-file-actions {
	flex-shrink: 0;
	display: flex;
	align-items: center;
	gap: .4rem;
}

.order-file-empty {
	color: var(--color-placeholder);
}

/* In the assignment's details the orderbon is a row you can tap */
.order-file-open {
	cursor: pointer;
}

.order-file-open .row-value {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	overflow-wrap: normal;
}

/* The invoice pop-up: which assignment, as a plain choice on the right of its row. The
   menu hangs out of the group, so this group doesn't clip. */
.invoice-assignment-group {
	overflow: visible;
}

.invoice-assignment-group > .field-row {
	background: none;
}

.invoice-assignment-group .field-dropdown-compact {
	margin: 0 -.35rem 0 auto;
}

.invoice-assignment-group .field-dropdown-compact .field-dropdown-button {
	max-width: 15rem;
	height: 2rem;
	padding: 0 .35rem 0 .5rem;
	border: 0;
	border-radius: .5rem;
	color: var(--color-uurbon-value);
	background: none;
}

.invoice-assignment-group .field-dropdown-compact .field-dropdown-button:hover,
.invoice-assignment-group .field-dropdown-compact.open .field-dropdown-button {
	background: var(--color-fill);
}

.invoice-assignment-group .field-dropdown .dropdown-menu {
	left: auto;
	right: 0;
}

.invoice-assignment-group .dropdown-value {
	text-overflow: ellipsis;
}

.invoice-assignment-group > .company-info {
	background: none;
}

#invoice-assignment-info:empty {
	display: none;
}

/* "Geen bedrijf" at the top of the list once a company is chosen: empties the field */
.company-badge-none {
	font-weight: 500;
	color: var(--color-text-secondary);
	background: var(--color-fill);
}

.company-suggest-none .name-suggest-text {
	color: var(--color-text-secondary);
}

/* ---------- A company's picture (companies.js, Sep 25) ---------- */
/* In the pop-up: the vehicle photo's layout with its camera and bin beside it, centred
   above the first group, in the same shape as the badge on the card (Sep 28), the
   picture zoomed to fill it. */
.company-hero {
	display: flex;
	justify-content: center;
	margin: .1rem 0 .9rem;
}

.company-logo {
	width: 8.25rem;                 /* the card badge's shape (3.3 × 2.6), a size up */
	height: 6.5rem;
	aspect-ratio: auto;
	color: var(--color-avatar-text);
	background: var(--color-avatar);
}

.company-logo.has-logo {
	background: #ffffff;
}

.company-logo img {
	object-fit: cover;              /* zoomed to fill the shape (Sep 28) */
}

.company-logo-letters {
	font-size: 1.6rem;
	font-weight: 700;
	letter-spacing: .04em;
}

/* The one button beside the picture: grey like the bin it replaced (Sep 28); its menu
   also holds Afbeelding verwijderen */
.company-logo-wrap .company-logo-badge {
	color: var(--color-on-company-photo-button);
	background: var(--color-company-photo-button);
}

.company-logo-wrap .company-logo-badge:hover {
	background: var(--color-company-photo-button-hover);
}

.company-logo-wrap .company-logo-badge svg {
	width: 1.05rem;
	height: 1.05rem;
	stroke-width: 1.8;
}

/* ---------- A company's colour, beside its picture (Sep 30, migration 032) ---------- */
/* The picture on the left with its camera button beside it, the colour on the right,
   the room between them left open; their bottoms in line with the camera button. On a
   phone too narrow for both, the colour goes under the picture, still on the right.
   The picture's empty left column (it kept the picture centred on its own) is dropped
   here. */
.company-hero {
	flex-wrap: wrap;
	justify-content: flex-start;
	align-items: flex-end;
	gap: .5rem .9rem;
}

.company-logo-slot:empty {
	display: none;
}

.company-hero .vehicle-photo-wrap {
	grid-template-columns: auto 1.9rem;
	margin-bottom: 0;
}

.company-hero .vehicle-photo-wrap .vehicle-photo-button {
	grid-column: 1;
}

.company-hero .vehicle-photo-wrap .avatar-badge {
	grid-column: 2;
}

/* The picture sits against the left edge now, so its menu (Afbeelding bekijken, Foto
   kiezen, …) opens from the picture's left edge towards the right instead of centred
   under it — centred, it stuck out past the side of the pop-up */
.company-hero .dropdown-menu.avatar-menu {
	left: 0;
	transform: none;
	transform-origin: top left;
}

/* Kleur above; under it the pipette (icon only) and the field in one line. Against the
   right edge, everything right-aligned. */
.company-color {
	margin-left: auto;
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	gap: .35rem;
}

.company-color-row {
	display: flex;
	align-items: center;
	gap: .4rem;
}

.company-color-label {
	padding-right: .15rem;
	font-size: .75rem;
	font-weight: 600;
	color: var(--color-label-secondary);
}

/* A small white field: the swatch on the left, the hex code after it */
.company-color-field {
	width: 7.5rem;
	display: flex;
	align-items: center;
	gap: .45rem;
	height: 2.1rem;
	padding: 0 .55rem 0 .4rem;
	border-radius: .6rem;
	corner-shape: squircle;
	background: var(--color-group);
	transition: box-shadow .15s ease-in-out;
}

.company-color-field:focus-within {
	box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-button-primary) 55%, transparent);
}

/* The colour itself; a tap opens the device's colour picker (the input over it) */
.company-color-swatch {
	position: relative;
	flex-shrink: 0;
	width: 1.35rem;
	height: 1.35rem;
	overflow: hidden;
	border-radius: .4rem;
	corner-shape: squircle;
	box-shadow: inset 0 0 0 1px rgb(0 0 0 / .14);
	cursor: pointer;
}

/* No colour yet: a checkerboard, the usual sign for "nothing" */
.company-color-swatch.is-empty {
	background: repeating-conic-gradient(#d9d9de 0 25%, #ffffff 0 50%) 50% / .5rem .5rem;
}

.company-color-swatch input {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	padding: 0;
	border: 0;
	opacity: 0;
	cursor: pointer;
}

.company-color-field input[name="color"] {
	flex: 1;
	width: 100%;
	min-width: 0;
	padding: 0;
	border: 0;
	outline: 0;
	font: inherit;
	font-size: .875rem;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	letter-spacing: .02em;
	text-transform: uppercase;
	color: var(--color-uurbon-value);
	background: transparent;
}

.company-color-field input[name="color"]::placeholder {
	font-weight: 500;
	color: var(--color-placeholder);
}

/* The pipette: a round icon button, the same size and grey as the camera button; the
   main colour while it is on */
.company-color-dropper {
	display: grid;
	flex-shrink: 0;
	place-items: center;
	width: 1.9rem;
	height: 1.9rem;
	padding: 0;
	border-radius: 50%;
	color: var(--color-on-company-photo-button);
	background: var(--color-company-photo-button);
	transition: background-color .15s ease-in-out, color .15s ease-in-out;
}

.company-color-dropper:hover {
	background: var(--color-company-photo-button-hover);
}

/* On (the ×): a soft blue-grey, the main colour lightened */
.company-color-dropper[aria-pressed="true"] {
	color: #ffffff;
	background: color-mix(in srgb, var(--brand) 68%, #ffffff);
}

.company-color-dropper[aria-pressed="true"]:hover {
	background: color-mix(in srgb, var(--brand) 80%, #ffffff);
}

.company-color-dropper svg {
	width: 1rem;
	height: 1rem;
	stroke-width: 1.9;
}

/* The pipette icon, or the × while it is on */
.company-color-dropper .dropper-icon-stop,
.company-color-dropper[aria-pressed="true"] .dropper-icon-pick {
	display: none;
}

.company-color-dropper[aria-pressed="true"] .dropper-icon-stop {
	display: block;
	stroke-width: 2.2;
}

/* ---------- The app's pipette (companies.js, Sep 30) ---------- */
/* While it is on, the loupe is the pointer: the arrow is hidden everywhere except over
   the × that stops it, and a finger sliding over the screen picks colours instead of
   scrolling. */
html.is-color-picking,
html.is-color-picking * {
	cursor: none !important;
	touch-action: none !important;
	user-select: none !important;
	-webkit-user-select: none !important;
}

html.is-color-picking [data-company-color-dropper],
html.is-color-picking [data-company-color-dropper] * {
	cursor: pointer !important;
}

/* The loupe, Photoshop's ring (Sep 30): a grey outer ring (#CDD1D8), inside it a thick
   ring that is all the colour under the pointer, open in the middle so what is being
   picked stays in sight, and a small solid dot on the exact point. No shadows. Moved
   with translate by companies.js; never in the way of the pointer. */
.color-loupe {
	--loupe-color: #ffffff;
	position: fixed;
	inset: auto;
	top: 0;
	left: 0;
	box-sizing: border-box;
	width: 4.5rem;
	height: 4.5rem;
	margin: -2.25rem 0 0 -2.25rem;
	padding: 0;
	overflow: visible;
	border: 6px solid #CDD1D8;
	border-radius: 50%;
	background: transparent;
	pointer-events: none;
}

/* The coloured ring, inside the grey one */
.color-loupe::before {
	content: "";
	position: absolute;
	inset: 0;
	border: 9px solid var(--loupe-color);
	border-radius: 50%;
}

.color-loupe.is-off {
	visibility: hidden;
}

/* The exact point: a white dot with a very thin dark grey line round it, like a game's
   crosshair dot. Flat, no shadow. */
.color-loupe-dot {
	position: absolute;
	/* Whole pixels (the ring is 72px, the dot 8px with its line), so the edge stays sharp */
	top: calc(50% - 4px);
	left: calc(50% - 4px);
	box-sizing: border-box;
	width: 8px;
	height: 8px;
	border: 1px solid #4A4A4F;
	border-radius: 50%;
	background: #ffffff;
}

/* On a card and in the pickers: the picture instead of the letters, filling the badge */
.company-badge.has-logo {
	overflow: hidden;
	background: #ffffff;
}

.company-badge img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* VCA: Soort and Diplomanummer as wide as each other and about as wide as the date
   under them (Sep 28) */
:is(#profile-form, #person-form, #formpage-form) [data-vca-tile] :is(.field-dropdown, .field-input[name="vca_number"]) {
	max-width: 11.25rem;
}

/* ---------- Team leaders in a company's pop-up (Sep 29) ---------- */
/* Each team leader is a white group like the Teamleider on the uurbon: "Teamleider"
   with the name and a round person button (pick a colleague), then E-mail and Telefoon,
   and a quiet "remove" row. "Teamleider toevoegen" is a group of its own under them.
   The shared rules are with the uurbon's (.hours-pick-group, .hours-pick-button). */
.company-contacts > .settings-group + .settings-group {
	margin-top: .6rem;
}

/* "Kiesbaar op facturen" is not about the team leaders: room between it and
   "+ Teamleider toevoegen" (Sep 30) */
.company-contacts + .settings-group {
	margin-top: 1.25rem;
}

/* What is missing, right under the field's group (companies.js, Sep 30); the field's
   name turns red too */
#company-form .company-field-error {
	min-height: 0;
	margin: .45rem .85rem .2rem;
	font-size: .875rem;
	line-height: 1.2rem;
}

#company-form .field-row.is-invalid > span:first-child {
	color: var(--color-error);
}

#company-form .company-color-field.is-invalid {
	box-shadow: 0 0 0 2px var(--color-error);
}

/* E-mail and phone under a team leader: the uurbon's "label  value" lines (Sep 30),
   with the value a field you can type in. Each <label> lays its name and field out
   straight into the two columns. */
#company-contacts .contact-info {
	grid-template-columns: max-content minmax(0, 1fr) auto;
	align-items: center;
	column-gap: .9rem;
	row-gap: .1rem;
}

/* The round − that takes the team leader off: on the right, over both lines, straight
   under the person button and the same size and grey */
#company-contacts .contact-remove {
	grid-column: 3;
	grid-row: 1 / span 2;
	display: grid;
	place-items: center;
	width: 1.9rem;
	height: 1.9rem;
	padding: 0;
	border-radius: 50%;
	color: var(--color-label-secondary);
	background: var(--color-fill);
	transition: background-color .15s ease-in-out, color .15s ease-in-out;
}

#company-contacts .contact-remove:hover {
	color: var(--color-destructive);
	background: var(--color-close-hover);
}

#company-contacts .contact-remove svg {
	width: 1.05rem;
	height: 1.05rem;
	stroke-width: 2.2;
}

#company-contacts .contact-info-line {
	display: contents;
}

#company-contacts .contact-info-line > span {
	color: var(--color-label-secondary);
}

#company-contacts .contact-info input {
	width: 100%;
	min-width: 0;
	height: 1.15rem;
	margin: 0;
	padding: 0;
	border: 0;
	outline: 0;
	font: inherit;
	color: var(--color-uurbon-value);
	background: transparent;
}

#company-contacts .contact-info input::placeholder {
	color: var(--color-placeholder);
}

/* A menu inside a white group (the project + on the new uurbon) must not be cut off
   by the group's rounded corners while it is open */
.settings-group:has(.dropdown.open) {
	overflow: visible;
}

/* ---------- The project row on the new uurbon (Sep 28) ---------- */
/* "Project ........ OP (+)": the kind that was chosen, and a round + that asks which */
.project-choice {
	display: flex;
	align-items: center;
	gap: .55rem;
	margin-left: auto;
}

.project-kind {
	font-size: .875rem;
	color: var(--color-text-secondary);
}

.project-row .dropdown {
	position: relative;
}

.project-add {
	display: grid;
	place-items: center;
	width: 1.9rem;
	height: 1.9rem;
	border-radius: 50%;
	color: var(--color-on-project-add);
	background: var(--color-project-add);
	transition: filter .15s ease-in-out;
}

.project-add:hover {
	filter: brightness(.92);
}

.project-add svg {
	width: 1.05rem;
	height: 1.05rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 2.4;
	stroke-linecap: round;
}

/* ---------- Projecten page (Sep 28) ---------- */
.project-badge {
	flex-shrink: 0;
	display: grid;
	place-items: center;
	width: 2.6rem;
	height: 2.6rem;
	border-radius: .7rem;
	corner-shape: squircle;
	color: var(--color-on-project-badge);
	background: var(--color-project-badge);
}

.project-badge svg {
	width: 1.35rem;
	height: 1.35rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.8;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.project-company {
	flex-shrink: 0;
	max-width: 35%;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-size: .75rem;
	color: var(--color-text-secondary);
}

.project-row.is-inactive .person-row-name,
.project-row.is-inactive .project-badge {
	opacity: .55;
}

#project-list {
	margin-top: .15rem;
}

#project-list .person-row {
	background: var(--color-card);
}

#project-list .person-row:hover {
	background: var(--color-card-hover);
}

/* ---------- "Exporteren" in the invoice pop-up (Sep 28) ---------- */
.button-export {
	display: inline-flex;
	align-items: center;
	gap: .35rem;
}

.button-export svg {
	width: 1.05rem;
	height: 1.05rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 2.1;
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* ---------- A project's hours and costs (Projecten, migration 023) ---------- */
.project-total-row {
	font-weight: 600;
}

/* The costs as a small ledger (Sep 30): header, rows, a total under a firm line.
   Every row is the same three columns — what, amount, remove — so the amounts sit
   in one right-aligned column; the header and the total leave the remove column
   empty (.project-cost-slot). */
.project-cost-head,
.project-cost-row,
.project-cost-total {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto auto;
	column-gap: .5rem;
}

.settings-row.project-cost-head {
	min-height: 2rem;
	padding-block: .35rem .2rem;
	font-size: .6875rem;
	font-weight: 600;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--color-label-secondary);
}

.project-cost-row {
	padding-block: .55rem;
}

.project-cost-main {
	display: grid;
	gap: .15rem;
	min-width: 0;
}

.project-cost-text {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-size: .9375rem;
	font-weight: 500;
}

.project-cost-meta {
	display: flex;
	align-items: center;
	gap: .4rem;
	font-size: .75rem;
	font-variant-numeric: tabular-nums;
	color: var(--color-label-secondary);
}

/* Expense or material, as a quiet tag rather than a word in a sentence */
.project-cost-tag {
	padding: .05rem .4rem;
	border-radius: .3rem;
	font-size: .6875rem;
	font-weight: 600;
	letter-spacing: .02em;
	color: var(--color-label-secondary);
	background: var(--color-fill);
}

.project-cost-value {
	min-width: 5.5rem;
	text-align: right;
	white-space: nowrap;
	font-variant-numeric: tabular-nums;
}

.project-cost-row .project-cost-value {
	font-size: .9375rem;
	font-weight: 500;
}

.project-cost-slot,
.project-cost-remove {
	width: 1.5rem;
}

.project-cost-remove {
	position: relative;
	z-index: 1;
	display: grid;
	place-items: center;
	height: 1.5rem;
	border-radius: 50%;
	color: var(--color-label-secondary);
	background: var(--color-fill);
	transition: color .15s ease-in-out, background-color .15s ease-in-out;
}

.project-cost-remove:hover {
	color: var(--color-mark-denied);
}

.project-cost-remove svg {
	width: .85rem;
	height: .85rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 2.2;
	stroke-linecap: round;
}

/* The total: bold, under a line in the text colour rather than the usual hairline */
.settings-row.project-cost-total {
	min-height: 2.8rem;
	font-weight: 700;
}

.sheet-compact .project-cost-total::before,
.project-cost-total::before {
	height: 1.5px;
	background: var(--color-label);
	opacity: .55;
}

/* Adding a cost: what for, how much (€ inside the field), expense or material, Add */
.project-cost-form {
	display: grid;
	grid-template-columns: auto 1fr;
	align-items: center;
	gap: .45rem;
	padding: .65rem .85rem .75rem;
	border-top: 1px solid var(--color-separator);
	background: var(--color-group);
}

.project-cost-form input[type="text"] {
	min-width: 0;
	height: 2rem;
	padding: 0 .6rem;
	border: 1px solid transparent;
	border-radius: .5rem;
	font: inherit;
	font-size: .875rem;
	color: var(--color-label);
	background: var(--color-fill);
}

.project-cost-form input[name="description"] {
	grid-column: 1 / -1;
}

/* The € is drawn inside the field: the field is the label, the input inside it is
   see-through */
.project-cost-amount {
	display: flex;
	align-items: center;
	width: 7.5rem;
	height: 2rem;
	padding-left: .6rem;
	border: 1px solid transparent;
	border-radius: .5rem;
	font-size: .875rem;
	color: var(--color-label-secondary);
	background: var(--color-fill);
	cursor: text;
}

.project-cost-amount:focus-within {
	border-color: var(--color-button-primary);
}

.project-cost-form .project-cost-amount input {
	flex: 1;
	width: 100%;
	height: 100%;
	padding: 0 .6rem 0 .3rem;
	border: 0;
	border-radius: 0;
	outline: none;
	text-align: right;
	font-variant-numeric: tabular-nums;
	background: transparent;
}

/* Expense | material as one segmented control, like the page filters */
.project-cost-kind {
	display: grid;
	grid-auto-columns: minmax(0, 1fr);
	grid-auto-flow: column;
	gap: .125rem;
	justify-self: end;
	padding: .15rem;
	border-radius: .6rem;
	background: var(--color-fill);
}

.project-cost-kind label {
	position: relative;
}

.project-cost-kind input {
	position: absolute;
	opacity: 0;
	pointer-events: none;
}

.project-cost-kind span {
	display: flex;
	align-items: center;
	justify-content: center;
	height: 1.7rem;
	padding: 0 .7rem;
	border-radius: .45rem;
	font-size: .8125rem;
	color: var(--color-text-secondary);
	cursor: pointer;
}

.project-cost-kind input:checked + span {
	font-weight: 600;
	color: var(--color-label);
	background: var(--color-filter-active);
	box-shadow: 0 1px 4px var(--color-filter-shadow);
}

.project-cost-kind input:focus-visible + span {
	outline: 2px solid var(--color-button-primary);
	outline-offset: 1px;
}

.project-cost-form .button {
	grid-column: 1 / -1;
	justify-self: end;
}

/* The team leader dropdown in the project form: its value on the right of the row */
#project-contact-row .field-dropdown {
	margin-left: auto;
}

/* ---------- User details: lower fields (Sep 28, round 8) ---------- */
/* Every white field on the User page and in a user's details is lower (was 2.1rem),
   and the date fields are exactly as high */
:is(#profile-form, #person-form, #formpage-form) {
	--user-field-h: 1.8rem;
}

:is(#profile-form, #person-form, #formpage-form) .field-input,
:is(#profile-form, #person-form, #formpage-form) .field-dropdown-button,
:is(#profile-form, #person-form, #formpage-form) .company-input,
:is(#profile-form, #person-form, #formpage-form) .date-pill-button {
	height: var(--user-field-h);
	border-radius: .55rem;
}

:is(#profile-form, #person-form, #formpage-form) .field + .field,
:is(#profile-form, #person-form, #formpage-form) .field + .field-pair,
:is(#profile-form, #person-form, #formpage-form) .field-pair + .field,
:is(#profile-form, #person-form, #formpage-form) .field-pair + .field-pair {
	margin-top: .4rem;
}

/* ---------- Rechten: compact, in two groups (Sep 28, round 8) ---------- */
.permission-group + .permission-group {
	margin-top: .75rem;
}

.permission-group-title {
	margin: 0 0 .1rem;
	font-size: .75rem;
	font-weight: 600;
	line-height: 1rem;
	letter-spacing: .02em;
	text-transform: uppercase;
	color: var(--color-text-secondary);
}

.permission-group .toggle-row {
	gap: .6rem;
	padding: .38rem 0;
	font-size: .875rem;
	line-height: 1.2rem;
}

.permission-group .toggle-row:first-of-type {
	padding-top: .2rem;
	border-top: 0;
}

.permission-group .toggle-row:last-child {
	padding-bottom: 0;
}

.permission-group .toggle-row small {
	margin-top: 0;
	font-size: .75rem;
	line-height: 1rem;
}

.permission-group .switch {
	width: 2.4rem;
	height: 1.3rem;
}

.permission-group .switch::before {
	top: .15rem;
	left: .15rem;
	width: 1.3rem;
	height: 1rem;
	border-radius: .5rem;
}

.permission-group .switch:checked::before {
	translate: .8rem 0;
}

/* ---------- Bedrijven cards (Sep 28, round 9) ---------- */
/* The picture's corners follow the card's: card radius (.8rem) minus the gap around
   the picture (.4rem), so the two curves run in parallel. */
/* Sharper still (Sep 28): .3rem, on every company card (Bedrijven and Mijn bedrijf) */
.company-row .company-badge {
	border-radius: .3rem;
	corner-shape: round;
}

/* The switch a touch lower than "as far from the bottom as from the right" */
#company-list .company-toggle,
#company-list .company-own-label {
	margin-bottom: .22rem;
}

/* Users list column 8: the vehicle's name, never wider than this */
.person-cell-vehicle {
	max-width: 9rem;
}

/* ---------- Certificaten on a person (profile.js, Sep 28, round 9) ---------- */
/* One block per certificate: its name with Vereist / Gewenst, the fields under it.
   A thin line between two blocks, as between the rows of the Rechten tile.
   What belongs together sits close, what doesn't gets room (Oct 20): inside a block the
   parts are tight, and around the line between two blocks there is a full rem, so a
   block's "Certificaat uploaden" reads as the end of that certificate rather than as a
   pair with whatever comes after the line. */
.cert-block:not([hidden]) ~ .cert-block:not([hidden]) {
	margin-top: 1rem;
	padding-top: .9rem;
	border-top: 1px solid var(--color-tile-separator);
}

.cert-head {
	display: flex;
	align-items: center;
	gap: .45rem;
	min-height: 1.6rem;
	margin-bottom: .25rem;
}

.cert-name {
	font-size: .9rem;
	font-weight: 600;
	color: var(--color-label);
}

.cert-chip {
	padding: .1rem .45rem;
	border-radius: .45rem;
	font-size: .68rem;
	font-weight: 600;
	line-height: 1rem;
}

.cert-chip-required { color: var(--color-on-cert-required); background: var(--color-cert-required); }
.cert-chip-recommended { color: var(--color-on-cert-recommended); background: var(--color-cert-recommended); }

/* The same size as a file's bin (.cert-file-delete), so the two line up on the right
   edge, one above the other (Oct 20: 1.6 and 1.8rem before) */
.cert-clear {
	display: grid;
	flex-shrink: 0;
	place-items: center;
	width: 1.7rem;
	height: 1.7rem;
	margin-left: auto;
	padding: 0;
	border: 0;
	border-radius: 50%;
	color: var(--color-on-badge-remove);
	background: var(--color-badge-remove);
	cursor: pointer;
}

.cert-clear:hover {
	background: var(--color-badge-remove-hover);
}

.cert-clear[hidden] {
	display: none;
}

.cert-clear svg {
	width: .9rem;
	height: .9rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.8;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.vca-state-info {
	font-weight: 500;
	color: var(--color-cert-info);
}

.cert-add {
	display: inline-block;
	margin-top: .8rem;
}

/* The same thin line between the last certificate and "Certificaat toevoegen" (Sep 29),
   with the same room around it as between two certificates (Oct 20): adding one is not
   part of the last certificate */
.cert-list:has(.cert-block:not([hidden])) + .cert-add {
	display: block;
	margin-top: 1rem;
	padding-top: .9rem;
	border-top: 1px solid var(--color-tile-separator);
}

.cert-add[hidden] {
	display: none;
}

.cert-add .dropdown-button {
	display: inline-flex;
	align-items: center;
	gap: .35rem;
}

.cert-add .dropdown-button svg {
	width: 1rem;
	height: 1rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 2;
	stroke-linecap: round;
}

/* ---------- Functies pop-up (users.js, Sep 28, round 9) ---------- */
/* Like a person's details: a white pop-up with the lists in grey tiles, compact rows
   with a thin line between them, grey buttons. */
.sheet-lookup {
	--sheet-bg: var(--color-panel);
	width: min(calc(100% - 2rem), 30rem);
	background: var(--color-panel);
}

.sheet-lookup .settings-head {
	margin-bottom: .5rem;
}

.lookup-tiles {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: .75rem;
}

.lookup-tile .tile-head {
	margin-bottom: .35rem;
}

.lookup-list {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
}

.lookup-item + .lookup-item {
	border-top: 1px solid var(--color-tile-separator);
}

.lookup-row {
	display: flex;
	align-items: center;
	gap: .6rem;
	width: 100%;
	min-height: 2.75rem;
	padding: .4rem 0;
	border: 0;
	font: inherit;
	text-align: left;
	color: var(--color-label);
	background: none;
	cursor: pointer;
}

.lookup-row-plain {
	cursor: default;
}

.lookup-text {
	display: grid;
	flex: 1;
	min-width: 0;
	gap: .05rem;
}

.lookup-name {
	font-size: .9rem;
	font-weight: 500;
	line-height: 1.2rem;
}

.lookup-sub {
	overflow: hidden;
	font-size: .75rem;
	line-height: 1rem;
	text-overflow: ellipsis;
	white-space: nowrap;
	color: var(--color-text-secondary);
}

.lookup-item.is-open .lookup-sub {
	white-space: normal;
}

.lookup-chevron svg {
	display: block;
	width: 1rem;
	height: 1rem;
	fill: none;
	stroke: var(--color-text-secondary);
	stroke-width: 2;
	stroke-linecap: round;
	stroke-linejoin: round;
	transition: rotate .2s ease-in-out;
}

.lookup-item.is-open .lookup-chevron svg {
	rotate: 90deg;
}

.lookup-bin {
	display: grid;
	place-items: center;
	flex-shrink: 0;
	width: 1.8rem;
	height: 1.8rem;
	padding: 0;
	border: 0;
	border-radius: 50%;
	color: var(--color-on-badge-remove);
	background: var(--color-badge-remove);
	cursor: pointer;
}

.lookup-bin:hover {
	background: var(--color-badge-remove-hover);
}

.lookup-bin svg,
.lookup-delete svg,
.lookup-add .button svg {
	width: .95rem;
	height: .95rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.9;
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* An open function: its certificates, each with Nee / Gewenst / Vereist */
.lookup-detail {
	padding: .1rem 0 .7rem;
}

.lookup-detail-label {
	margin: 0 0 .3rem;
	font-size: .7rem;
	font-weight: 600;
	letter-spacing: .02em;
	text-transform: uppercase;
	color: var(--color-text-secondary);
}

.lookup-req-row {
	display: flex;
	flex-wrap: wrap;               /* on a narrow phone the switch goes under the name */
	align-items: center;
	justify-content: space-between;
	gap: .25rem .6rem;
	padding: .25rem 0;
}

.lookup-req-row .req-switch {
	margin-left: auto;
}

.lookup-req-name {
	flex: 1 1 5.5rem;
	min-width: 0;
	overflow: hidden;
	font-size: .85rem;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.req-switch {
	display: inline-flex;
	flex-shrink: 0;
	gap: 2px;
	padding: 2px;
	border-radius: .6rem;
	background: var(--color-req-track);
}

.req-choice {
	position: relative;
	cursor: pointer;
}

.req-choice input {
	position: absolute;
	opacity: 0;
	pointer-events: none;
}

.req-choice span {
	display: block;
	padding: .2rem .55rem;
	border-radius: .5rem;
	font-size: .72rem;
	font-weight: 500;
	line-height: 1.1rem;
	color: var(--color-text-secondary);
}

.req-choice input:checked + span {
	color: var(--color-label);
	background: var(--color-req-active);
	box-shadow: 0 1px 2px var(--color-filter-shadow);
}

.req-choice-required input:checked + span {
	color: var(--color-on-cert-required);
	background: var(--color-cert-required);
}

.req-choice-recommended input:checked + span {
	color: var(--color-on-cert-recommended);
	background: var(--color-cert-recommended);
}

.req-choice input:focus-visible + span {
	outline: 2px solid var(--color-accent);
	outline-offset: 1px;
}

.lookup-delete {
	display: inline-flex;
	align-items: center;
	gap: .35rem;
	margin-top: .5rem;
}

/* Adding one: the field and the button on one line under the list */
.lookup-add {
	display: flex;
	gap: .5rem;
	margin-top: .6rem;
}

.lookup-add .field-input {
	flex: 1;
	min-width: 0;
	height: 2rem;
	border-color: transparent;
	border-radius: .6rem;
	font-size: .9rem;
}

.lookup-add .field-input:focus {
	border-color: var(--color-accent);
}

.lookup-add .button {
	display: inline-flex;
	align-items: center;
	gap: .3rem;
	flex-shrink: 0;
}

.lookup-error:empty {
	display: none;
}

.lookup-tile .tile-note {
	margin-top: .5rem;
}

/* ---------- Meldingen: calmer choices (Sep 28, round 10) ---------- */
/* The picked option has a coloured background instead of an outline: Blauw and Rood in
   the colour of the line they make, Voor in the brand's light tint. */
.notify-tone span,
.notify-chip span {
	border-color: transparent;
}

.notify-tone input:checked + span,
.notify-chip input:checked + span {
	border-color: transparent;
	box-shadow: none;
	font-weight: 600;
	color: var(--color-on-day-booked);
	background: var(--color-day-booked);
}

.notify-tone-blue input:checked + span {
	color: var(--color-on-message-blue);
	background: var(--color-message-blue);
}

.notify-tone-red input:checked + span {
	color: var(--color-on-message-red);
	background: var(--color-message-red);
}

.notify-tone-green input:checked + span {
	color: var(--color-on-message-green);
	background: var(--color-message-green);
}

/* No ring around the message box while typing in it */
.notify-compose .field-textarea,
.notify-compose .field-textarea:focus {
	border-color: transparent;
	box-shadow: none;
}

/* Teamleider with "optioneel" after it, in the row itself (Sep 29) */
#hours-form .leader-label {
	display: inline-flex;
	flex-shrink: 0;
	align-items: baseline;
	gap: .35rem;
	white-space: nowrap;
}

#hours-form .leader-label .field-label-optional {
	font-size: .875rem;
	font-weight: 400;
}

/* "(optioneel)" lighter than "Deadline" */
.field-label-optional {
	font-weight: 400;
	color: var(--color-placeholder);
}

/* Functies / Dienstverbanden: one dropdown with a tick box per option */
.notify-multi {
	max-width: 20rem;
}

.notify-multi .dropdown-value {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.notify-multi .dropdown-value.is-placeholder {
	color: var(--color-placeholder);
}

.notify-multi-menu {
	max-height: 16rem;
	overflow-y: auto;
}

.notify-multi-option {
	display: flex;
	align-items: center;
	gap: .55rem;
	cursor: pointer;
}

.notify-multi-option input {
	position: absolute;
	opacity: 0;
	pointer-events: none;
}

.notify-multi-box {
	display: grid;
	place-items: center;
	flex-shrink: 0;
	width: 1.1rem;
	height: 1.1rem;
	border: 1.5px solid var(--color-placeholder);
	border-radius: .3rem;
}

.notify-multi-box svg {
	width: .8rem;
	height: .8rem;
	fill: none;
	stroke: transparent;
	stroke-width: 3;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.notify-multi-option input:checked + .notify-multi-box {
	border-color: var(--color-accent);
	background: var(--color-accent);
}

.notify-multi-option input:checked + .notify-multi-box svg {
	stroke: var(--color-on-button-primary);
}

.notify-multi-option input:focus-visible + .notify-multi-box {
	outline: 2px solid var(--color-accent);
	outline-offset: 2px;
}

/* ---------- Certificates: proof and approval (Sep 28, round 10) ---------- */
.cert-chip-pending { color: var(--color-on-cert-pending); background: var(--color-cert-pending); }

.cert-note {
	margin: 0 0 .45rem;
	font-size: .78rem;
	line-height: 1.1rem;
	color: var(--color-text-secondary);
}

.cert-facts {
	margin: 0 0 .35rem;
}

/* A certificate's details are one size smaller than the rows of the other tiles, and
   tighter: they are the details *of* the name above them (Oct 20: .2 → .18rem) */
.cert-facts > div {
	padding: .18rem 0;
	font-size: .85rem;
	line-height: 1.25;
}

/* Voertuigen: the vehicle's details under its field, in the same small lines */
.vehicle-info {
	margin: .55rem .1rem 0;
}

/* The uploaded files: one row each, a tap opens it */
.cert-files {
	display: grid;
	/* One column that never grows past the tile: a long file name is cut off with …
	   instead of pushing the bin out (Sep 29) */
	grid-template-columns: minmax(0, 1fr);
	gap: .3rem;
	margin: 0 0 .5rem;
	padding: 0;
	list-style: none;
}

.cert-file {
	display: flex;
	align-items: center;
	gap: .4rem;
	min-width: 0;
}

.cert-file-open {
	display: flex;
	flex: 1;
	align-items: center;
	gap: .45rem;
	min-width: 0;
	min-height: 2rem;
	padding: .3rem .6rem;
	border: 0;
	border-radius: .55rem;
	font: inherit;
	font-size: .82rem;
	text-align: left;
	color: var(--color-label);
	background: var(--color-field);
	cursor: pointer;
}

.cert-file-open span {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.cert-file-open svg,
.cert-file-delete svg,
.cert-actions .button svg {
	flex-shrink: 0;
	width: 1rem;
	height: 1rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.8;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.cert-file-open svg {
	color: var(--color-text-secondary);
}

.cert-file-delete {
	display: grid;
	place-items: center;
	flex-shrink: 0;
	width: 1.7rem;
	height: 1.7rem;
	padding: 0;
	border: 0;
	border-radius: 50%;
	color: var(--color-on-badge-remove);
	background: var(--color-badge-remove);
	cursor: pointer;
}

.cert-file-delete svg {
	width: .9rem;
	height: .9rem;
}

/* Close under its certificate's details and files (Oct 20: .5 → .4rem): it belongs to them */
.cert-actions {
	display: flex;
	flex-wrap: wrap;
	gap: .4rem;
	margin-top: .4rem;
}

.cert-actions .button {
	display: inline-flex;
	align-items: center;
	gap: .35rem;
}

/* Sizes (Sep 30): "Certificaat uploaden" under each certificate is the small one;
   "Certificaat toevoegen" under them all is its bigger brother, still smaller than an
   ordinary small button */
.cert-actions .button.button-small {
	gap: .3rem;
	min-height: 1.75rem;
	padding: 0 .7rem 0 .6rem;
	font-size: .78rem;
}

.cert-actions .button.button-small svg {
	width: .85rem;
	height: .85rem;
}

.cert-add .button.button-small.dropdown-button {
	gap: .35rem;
	min-height: 2rem;
	padding: 0 .85rem 0 .7rem;
	font-size: .85rem;
}

.cert-add .button.button-small.dropdown-button svg {
	width: .95rem;
	height: .95rem;
}

/* ---------- Mijn bedrijf on the User page (Sep 28, round 10) ---------- */
.my-company-text {
	margin: -.25rem 0 .7rem;
	font-size: .85rem;
	line-height: 1.25rem;
	color: var(--color-text-secondary);
}

.my-company-add {
	display: inline-flex;
	align-items: center;
	gap: .35rem;
}

.my-company-add svg {
	width: 1rem;
	height: 1rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 2;
	stroke-linecap: round;
}

/* One card, never wider than the tile (the list's usual 15rem minimum pushed it out
   of a narrow column, Sep 29) */
.my-company-list {
	grid-template-columns: minmax(0, 1fr);
}

/* The same card as on Bedrijven, white on the grey tile */
.my-company-list .person-row {
	padding: .4rem .75rem .4rem .4rem;
	background: var(--color-tile-item);
}

.my-company-list .person-row:hover {
	background: var(--color-tile-item-hover);
}

/* ---------- Uurbon: Werknemer, Bedrijf, Project, Teamleider (Sep 29, round 2) ---------- */
/* Four sections built exactly like the company pickers on the invoice pop-up: a small
   title, one white group with "Naam" / "Soort" on the left and the choice on the right
   next to a round grey button (.company-arrow), and the details a size smaller
   underneath (.company-info). The button is an arrow for Bedrijf and Project and a
   person — or the employee's photo — for Werknemer and Teamleider (.hours-pick-button).
   Replaces the separate picker squares of Sep 28. */

/* The choice sits on the right, like the company on the invoice. Shared with the team
   leaders in a company's pop-up (#company-contacts, Sep 29), which look the same. */
:is(#hours-form, #company-contacts) :is(.employee-field, .leader-field) {
	flex: 1;
	min-width: 0;
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: .35rem;
}

:is(#hours-form, #hours-sheet, #company-contacts) .hours-pick-group .field-row {
	gap: .75rem;
}

:is(#hours-form, #company-contacts) :is(#hours-employee-name, .leader-field input) {
	flex: 1;
	width: auto;
	min-width: 0;
	text-align: right;
	font-weight: 500;
	color: var(--color-uurbon-value);
}

#hours-form .employee-field .employee-pick {
	margin-left: 0;
}

/* The group draws the white: while the Soort menu is open the group lets it hang out
   (overflow: visible), and white rows of their own would then show square corners */
:is(#hours-form, #hours-sheet, #company-contacts) .hours-pick-group > :is(.field-row, .company-info) {
	background: transparent;
}

/* The details start in line with "Naam" (the rows here are .85rem in, not 1rem) */
:is(#hours-form, #hours-sheet, #company-contacts) .hours-pick-group .company-info {
	padding-inline: .85rem;
}

/* The lines between the parts of these four run from edge to edge (Sep 29); the
   hours table keeps its inset lines */
:is(#hours-form, #hours-sheet, #company-contacts) .hours-pick-group .company-info::before {
	left: 0;
	right: 0;
}

:is(#hours-form, #hours-sheet, #company-contacts) .hours-pick-group > .field-row:not(:first-child)::before {
	content: "";
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: 1px;
	background: var(--color-separator);
}

/* "Label  value" lines: the labels in one column, the values lined up after them */
:is(#hours-form, #hours-sheet) .hours-info {
	grid-template-columns: max-content minmax(0, 1fr);
	column-gap: .9rem;
	row-gap: .1rem;
}

:is(#hours-form, #hours-sheet) .hours-info > span:nth-child(odd) {
	color: var(--color-label-secondary);
}

:is(#hours-form, #hours-sheet) .hours-info > span:nth-child(even) {
	overflow-wrap: anywhere;
}

:is(#hours-form, #hours-sheet) .hours-info > .company-info-empty {
	grid-column: 1 / -1;
}

/* The round person button: the same size and grey as the invoice's arrow */
:is(#hours-form, #company-contacts) .hours-pick-button {
	display: grid;
	flex-shrink: 0;
	place-items: center;
	width: 1.9rem;
	height: 1.9rem;
	padding: 0;
	overflow: hidden;
	border-radius: 50%;
	color: var(--color-label-secondary);
	background: var(--color-fill);
	transition: background-color .15s ease-in-out;
}

:is(#hours-form, #company-contacts) .hours-pick-button:hover {
	background: var(--color-close-hover);
}

:is(#hours-form, #company-contacts) .hours-pick-button svg {
	width: 1.05rem;
	height: 1.05rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 2.2;
	stroke-linecap: round;
}

#hours-form .employee-pick .employee-avatar {
	width: 100%;
	height: 100%;
	font-size: .62rem;
}

/* Soort: OP / Opdracht, or "Selecteer soort" in the placeholder grey; the whole row
   opens the menu */
#hours-form .project-row {
	cursor: pointer;
}

#hours-form .project-choice {
	gap: .35rem;
}

#hours-form .project-kind {
	font-size: inherit;
	font-weight: 500;
	color: var(--color-uurbon-value);
}

#hours-form .project-kind {
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

#hours-form .project-kind.is-empty {
	font-weight: 400;
	color: var(--color-placeholder);
}

#hours-form .project-pick svg {
	width: 1.05rem;
	height: 1.05rem;
	stroke-width: 2.2;
	fill: none;
	stroke: currentColor;
	stroke-linecap: round;
	stroke-linejoin: round;
}


/* The Project menu hangs over the fields under it */
#hours-form .project-row {
	z-index: 3;
}

/* ---------- Uurbon: the project pop-up (Sep 29) ---------- */
/* A little smaller than the uurbon it opens over, and always this tall: the list at
   the bottom fills whatever room is left. Close, title and Opslaan on top; a search
   field; Recent (two, more behind a quiet button); then the matches. */
.project-picker {
	width: min(calc(100% - 3rem), 28rem);
	max-width: calc(100% - 3rem);
	height: min(calc(100% - 3.5rem), 46rem);
}

.project-picker .settings-inner {
	display: flex;
	flex-direction: column;
	box-sizing: border-box;
	height: 100%;
	max-height: none;
	overflow: hidden;
}

.project-search {
	display: flex;
	flex-shrink: 0;
	align-items: center;
	gap: .5rem;
	min-height: 2.6rem;
	padding: 0 .85rem;
	border-radius: .625rem;
	color: var(--color-label-secondary);
	background: var(--color-group);
}

.project-search svg {
	flex-shrink: 0;
	width: 1.05rem;
	height: 1.05rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 2.2;
	stroke-linecap: round;
}

.project-search input {
	flex: 1;
	min-width: 0;
	margin: 0;
	padding: 0;
	border: 0;
	outline: 0;
	font: inherit;
	color: var(--color-label);
	background: transparent;
	appearance: none;
}

.project-search input::placeholder {
	color: var(--color-placeholder);
}

.project-search input::-webkit-search-cancel-button {
	appearance: none;
}

/* No Opslaan in the header any more (a tap chooses and closes): an empty box as wide
   as the close button keeps the title centred */
.project-picker-spacer {
	width: 2.25rem;
}

/* "Geen project": its own small group above Recent */
.project-none {
	flex-shrink: 0;
	margin-top: .9rem;
}

.project-option-none {
	color: var(--color-text-secondary);
}

.project-recent {
	flex-shrink: 0;
	display: flex;
	flex-direction: column;
}

/* The rest of the pop-up: the matches, scrolling on their own */
.project-results {
	flex: 1;
	min-height: 3rem;
	margin-top: .9rem;
	overflow-y: auto;
}

.project-option {
	position: relative;
	display: flex;
	align-items: center;
}

.project-option + .project-option::before {
	content: "";
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: 1px;
	background: var(--color-separator);
}

.project-option.is-chosen {
	background: color-mix(in srgb, var(--color-button-primary) 9%, var(--color-group));
}

.project-option-pick {
	display: flex;
	flex: 1;
	align-items: center;
	gap: .6rem;
	min-width: 0;
	min-height: 2.9rem;
	margin: 0;
	padding: .45rem .85rem;
	border: 0;
	font: inherit;
	text-align: left;
	color: var(--color-label);
	background: none;
	cursor: pointer;
}

.project-option-text {
	display: grid;
	flex: 1;
	min-width: 0;
}

.project-option-title {
	font-weight: 500;
	font-variant-numeric: tabular-nums;
}

.project-option-text small {
	overflow: hidden;
	font-size: .8125rem;
	line-height: 1.15rem;
	white-space: nowrap;
	text-overflow: ellipsis;
	color: var(--color-text-secondary);
}

.project-option-check {
	flex-shrink: 0;
	width: 1.15rem;
	height: 1.15rem;
	fill: none;
	stroke: var(--color-button-primary);
	stroke-width: 2.4;
	stroke-linecap: round;
	stroke-linejoin: round;
	visibility: hidden;
}

.project-option.is-chosen .project-option-check {
	visibility: visible;
}

/* Only off the Recent list: small and grey, never red — the project stays */
.project-option-forget {
	display: grid;
	flex-shrink: 0;
	place-items: center;
	width: 1.5rem;
	height: 1.5rem;
	margin: 0 .7rem 0 -.2rem;
	padding: 0;
	border: 0;
	border-radius: 50%;
	color: var(--color-label-secondary);
	background: var(--color-fill);
	cursor: pointer;
}

.project-option-forget:hover {
	background: var(--color-close-hover);
}

.project-option-forget svg {
	width: .8rem;
	height: .8rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 2.4;
	stroke-linecap: round;
}

/* "Nog 3 tonen": a quiet line under Recent, not a button that competes with Opslaan */
.project-recent-more {
	align-self: flex-end;
	margin: .2rem .3rem 0;
	padding: .2rem .5rem;
	border: 0;
	font: inherit;
	font-size: .8125rem;
	color: var(--color-label-secondary);
	background: none;
	cursor: pointer;
}

.project-recent-more:hover {
	color: var(--color-label);
}

.project-list-empty {
	margin: 0;
	padding: .75rem .85rem;
	font-size: .875rem;
	font-style: italic;
	color: var(--color-text-secondary);
}

/* ---------- A person's details: a page of its own (Sep 29) ---------- */
/* The office's page for one person (#users/<id>) and the User page share this. Four
   columns in a fixed order (script.js, arrangeGroups): neighbouring ones share a
   column when four don't fit, one column on a phone. */
.person-grid {
	--group-min: 15rem;
	display: flex;
	align-items: flex-start;
	gap: var(--tile-gap);
}

.person-grid:not(:has(> .tile-col)) {
	flex-direction: column;
	align-items: stretch;
}

/* These pages get room for four columns (the rest keeps three). The Gebruikers list
   too since Oct 20: ten columns of a person on one line need it. */
.content-inner:has(:is([data-page="person"], [data-page="person-form"], [data-page="user"], [data-page="users"]):not([hidden])) {
	--page-width: calc(4 * var(--tile-max) + 3 * var(--tile-gap) + 2rem);
}

.person-group {
	display: flex;
	flex-direction: column;
	gap: var(--tile-gap);
}

/* The title is a path back: "Gebruikers › Voornaam Achternaam" (tap Gebruikers to go back) */
.panel-crumbs {
	display: flex;
	align-items: center;
	gap: .15rem;
}

.crumb-link {
	flex-shrink: 0;
	color: color-mix(in srgb, var(--color-text-secondary) 55%, transparent);
	text-decoration: none;
	transition: color .15s ease-in-out;
}

.crumb-link:hover {
	color: var(--color-panel-title);
}

.crumb-sep {
	flex-shrink: 0;
	width: 1.15rem;
	height: 1.15rem;
	fill: none;
	stroke: color-mix(in srgb, var(--color-text-secondary) 55%, transparent);
	stroke-width: 2.4;
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* On a phone only a back arrow before the name: the name gets the room */
.crumb-back {
	display: none;
	width: 1.6rem;
	height: 1.6rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 2.4;
	stroke-linecap: round;
	stroke-linejoin: round;
}

@media (max-width: 40rem) {
	.crumb-link {
		display: grid;
		place-items: center;
		margin-left: -.35rem;
	}

	.crumb-back {
		display: block;
	}

	.crumb-link span,
	.crumb-sep {
		display: none;
	}
}

.crumb-current {
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
}

.page-person .button-save {
	flex-shrink: 0;
	white-space: nowrap;
}

/* A field with its name inside on the left and the value on the right. White on the
   grey tile, no outline (the accent one shows while typing), as low as the other
   fields on these pages. Read-only it is the same box with the value as text. */
/* The gaps between fields and the room inside them are the project pop-up's (a .6rem gap
   between its groups, .85rem inside a row, Sep 29). The tile titles keep their own. */
.pfield {
	position: relative;
	display: flex;
	align-items: center;
	gap: .75rem;
	min-width: 0;
	min-height: 2.15rem;
	padding: 0 .85rem;
	border: 1px solid transparent;
	border-radius: .6rem;
	corner-shape: squircle;
	font-size: .9rem;
	color: var(--color-text);
	background: var(--color-field);
	transition: border-color .15s ease-in-out;
}

.pfield + .pfield,
.pfield + .field,
.field + .pfield {
	margin-top: .6rem;
}

/* A date keeps its name above it (Geboortedatum, like the dates under Certificaten) */
:is(#profile-form, #person-form, #formpage-form) .pfield + .date-pill-field .field-label {
	margin-left: .2rem;
}

.pfield:focus-within {
	border-color: var(--color-accent);
}

.pfield-label {
	flex-shrink: 0;
	max-width: 55%;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-size: .8125rem;
	font-weight: 500;
	color: var(--color-text-secondary);
}

.pfield-input {
	flex: 1;
	min-width: 0;
	height: 2rem;
	margin: 0;
	padding: 0;
	border: 0;
	outline: 0;
	font: inherit;
	text-align: right;
	color: var(--color-text);
	background: transparent;
}

.pfield-input[type="number"] {
	appearance: textfield;
}

.pfield-input[type="number"]::-webkit-inner-spin-button,
.pfield-input[type="number"]::-webkit-outer-spin-button {
	appearance: none;
	margin: 0;
}

/* A long value (an address, an IBAN) goes on over more lines rather than being cut */
.pfield-value {
	flex: 1;
	min-width: 0;
	padding-block: .45rem;
	line-height: 1.25;
	text-align: right;
	overflow-wrap: break-word;
}

/* Personeelsnummer and a login's e-mail: nobody can change them, so no white field, just
   the name and the value (the look from before Sep 29). On your own page the rows are
   spaced like all the others (#profile-form, further down). */
.pfield-fixed {
	padding: .15rem .1rem .1rem;
	font-size: .9rem;
}

.pfield-fixed dd {
	font-weight: 400;
}

.pfield-fixed + .pfield {
	margin-top: .6rem;
}

/* Read-only. The office's page keeps every box white. */
.pfield.is-static {
	background: var(--color-field);
}

/* On the person's own page nothing can be changed by them, so it doesn't look like a
   field at all (Sep 30): the plain lines of Rechten and Personeelsnummer — the name left
   in grey, the value right, a thin line between two — instead of dimmed boxes. Takes
   less room too. */
/* Compact and the same everywhere (Oct 20): every read-only row on this page — these,
   Personeelsnummer and Rechten (both <dl class="facts">) — has the same room above and
   below its text, so the text sits halfway between two lines. Before, each kind had its
   own: .5rem here, nothing under Personeelsnummer, a bigger font in Rechten. The first
   row of a tile starts right under the title, the last ends at the tile's padding. */
#profile-form {
	--profile-row-pad: .35rem;
}

#profile-form .pfield.is-static {
	min-height: 0;
	padding: var(--profile-row-pad) .1rem;
	border: 0;
	border-radius: 0;
	font-size: .9rem;
	background: none;
}

#profile-form .tile-head + .pfield.is-static,
#profile-form .pfields > .pfield.is-static:first-child {
	padding-top: 0;
}

#profile-form .pfield.is-static:last-child {
	padding-bottom: 0;
}

#profile-form .pfield-fixed {
	padding: 0 .1rem;
}

#profile-form .facts:not(.cert-facts) {
	font-size: .9rem;
	line-height: 1.25;
}

#profile-form .facts:not(.cert-facts) > div {
	padding-block: var(--profile-row-pad);
}

#profile-form .facts:not(.cert-facts) > div:first-child {
	padding-top: 0;
}

/* Only the very last row of a tile ends without room under it: Personeelsnummer has
   rows under it, below a line */
#profile-form .facts:not(.cert-facts):last-child > div:last-child {
	padding-bottom: 0;
}

/* The tiles themselves a little tighter too: less padding, the title closer to its rows */
#profile-form .tile {
	padding: .8rem .9rem .85rem;
}

#profile-form .tile-head {
	margin-bottom: .55rem;
}

#profile-form .profile-card {
	padding-block: 1rem;
}

#profile-form .profile-name {
	margin-top: .55rem;
}

#profile-form :is(.pfield.is-static, .pfield-fixed) + .pfield.is-static {
	margin-top: 0;
	border-top: 1px solid var(--color-tile-separator);
}

#profile-form .pfield.is-static .pfield-label {
	font-size: inherit;
	font-weight: 400;
	color: var(--color-text-secondary);
}

#profile-form .pfield.is-static .pfield-value {
	padding-block: 0;
}

/* The values on your own page (Sep 30): halfway between the black of the text and the
   grey of the names — not as loud as black, still clearly the value. The same for
   Personeelsnummer, the certificates' and the vehicle's details. */
#profile-form :is(.pfield.is-static .pfield-value, .pfield-fixed dd, .cert-facts dd) {
	color: color-mix(in srgb, var(--color-text) 25%, var(--color-text-secondary));
}

/* A menu: the whole right part opens it; the value and arrow sit against the right edge,
   and the list opens under them, lined up on the right */
.pfield-select {
	padding-right: .45rem;
}

:is(#profile-form, #person-form, #formpage-form, #vehicle-form) .pfield .field-dropdown {
	flex: 1;
	min-width: 0;
	max-width: none;
}

:is(#profile-form, #person-form, #formpage-form, #vehicle-form) .pfield .field-dropdown-button {
	justify-content: flex-end;
	gap: .3rem;
	height: 2rem;
	padding: 0 .3rem 0 0;
	border: 0;
	font-size: inherit;
	background: transparent;
}

.pfield .field-dropdown-button .dropdown-value {
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* The list opens under the whole field, exactly as wide as it, and shows ten choices
   before it scrolls (Functie) */
:is(#person-form, #formpage-form, #vehicle-form) .pfield .field-dropdown {
	position: static;
}

:is(#person-form, #formpage-form, #vehicle-form) .pfield .field-dropdown .dropdown-menu {
	left: -1px;
	right: -1px;
	width: auto;
	min-width: 0;
	max-width: none;
	max-height: calc(10 * 2.1625rem + .7rem);
}

.my-company-list + .pfields {
	margin-top: .6rem;
}

/* ---------- Company pop-up: who it belongs to, and only looking (Sep 29) ---------- */
/* Built like the invoice's Opdracht row: the name as a plain choice on the right, the
   menu hanging out of the group (so the group doesn't clip, and its row has no white
   of its own that would show square corners) */
.company-owner-group {
	overflow: visible;
}

.company-owner-group > .field-row {
	background: none;
}

.company-owner-group .field-dropdown-compact {
	margin: 0 -.35rem 0 auto;
}

.company-owner-group .field-dropdown-compact .field-dropdown-button {
	max-width: 15rem;
	height: 2rem;
	padding: 0 .35rem 0 .5rem;
	border: 0;
	border-radius: .5rem;
	color: var(--color-uurbon-value);
	background: none;
}

.company-owner-group .field-dropdown-compact .field-dropdown-button:hover,
.company-owner-group .field-dropdown-compact.open .field-dropdown-button {
	background: var(--color-fill);
}

.company-owner-group .dropdown-value {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.company-owner .dropdown-menu {
	left: auto;
	right: 0;
	max-height: calc(10 * 2.1625rem + .7rem);
	overflow-y: auto;
}

.company-owner [role="option"]:disabled {
	cursor: default;
	opacity: .5;
}

.option-note {
	font-size: .8em;
	color: var(--color-text-secondary);
}

/* Read-only: no hints that look like values, and nothing that invites typing */
#company-sheet.is-readonly input::placeholder {
	color: transparent;
}

#company-sheet.is-readonly input {
	cursor: default;
}

/* ---------- Vehicles: the office's own order (Sep 29) ---------- */
/* The small round button next to Nieuw: two arrows beside three lines */
#vehicle-order-open svg {
	fill: none;
	stroke: currentColor;
	stroke-width: 1.8;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.vehicle-order-note {
	margin: .1rem .85rem .6rem;
}

/* One white list; a row can be lifted out of it, so the list doesn't clip and the
   first and last rows carry the rounded corners themselves */
.vehicle-order-list {
	position: relative;
	margin: 0;
	padding: 0;
	overflow: visible;
	list-style: none;
	background: none;
}

.vehicle-order-row {
	position: relative;
	display: flex;
	align-items: center;
	gap: .7rem;
	min-height: 3.3rem;
	padding: .45rem .4rem .45rem .85rem;
	background: var(--color-group);
}

.vehicle-order-row:first-child {
	border-radius: 1.25rem 1.25rem 0 0;
}

.vehicle-order-row:last-child {
	border-radius: 0 0 1.25rem 1.25rem;
}

.vehicle-order-row:only-child {
	border-radius: 1.25rem;
}

.vehicle-order-row + .vehicle-order-row::before {
	content: "";
	position: absolute;
	top: 0;
	left: .85rem;
	right: .85rem;
	height: 1px;
	background: var(--color-separator);
}

/* Picked up: it follows the finger, lifted above the rest */
.vehicle-order-row.is-dragging {
	z-index: 2;
	border-radius: .9rem;
	transform: translateY(var(--drag-y, 0)) scale(1.02);
	box-shadow: 0 .6rem 1.6rem var(--color-menu-shadow);
}

.vehicle-order-row.is-dragging::before,
.vehicle-order-row.is-dragging + .vehicle-order-row::before {
	opacity: 0;
}

.vehicle-order-number {
	flex-shrink: 0;
	min-width: 1.3rem;
	font-size: .875rem;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	text-align: center;
	color: var(--color-label-secondary);
}

.vehicle-order-photo {
	--photo-size: 2.4rem;
	border-radius: .55rem;
}

.vehicle-order-main {
	display: flex;
	flex: 1;
	flex-direction: column;
	min-width: 0;
}

.vehicle-order-name,
.vehicle-order-sub {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.vehicle-order-name {
	font-weight: 600;
	color: var(--color-label);
}

.vehicle-order-sub {
	font-size: .8125rem;
	color: var(--color-label-secondary);
}

.vehicle-order-row.is-inactive .vehicle-order-name {
	color: var(--color-label-secondary);
}

/* The six dots: the handle to pick a vehicle up by */
.vehicle-order-grip {
	display: grid;
	flex-shrink: 0;
	place-items: center;
	width: 2.4rem;
	height: 2.6rem;
	padding: 0;
	border: 0;
	border-radius: .6rem;
	color: var(--color-label-secondary);
	background: none;
	cursor: grab;
	touch-action: none;
}

.vehicle-order-grip:hover,
.vehicle-order-grip:focus-visible {
	background: var(--color-fill);
}

.vehicle-order-row.is-dragging .vehicle-order-grip {
	cursor: grabbing;
}

.vehicle-order-grip svg {
	width: 1.25rem;
	height: 1.25rem;
	fill: currentColor;
}

/* ---------- Auto save (script.js, Oct 2) ---------- */
/* "Opgeslagen" in a form's header while auto save is on. On a phone only the cloud. */
.autosave-status {
	display: inline-flex;
	flex-shrink: 0;
	align-items: center;
	gap: .3rem;
	margin-right: .35rem;
	font-size: .75rem;
	font-weight: 600;
	white-space: nowrap;
	color: var(--color-text-secondary);
	transition: color .2s ease-in-out;
}

.autosave-status svg {
	width: 1.2rem;
	height: 1.2rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.8;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.autosave-status[data-state="failed"] {
	color: var(--color-on-message-red);
}

.autosave-status[data-state="saving"] svg {
	animation: autosave-pulse 1s ease-in-out infinite;
}

@keyframes autosave-pulse {
	50% { opacity: .35; }
}

@media (prefers-reduced-motion: reduce) {
	.autosave-status[data-state="saving"] svg { animation: none; }
}

@media (max-width: 30rem) {
	.autosave-text {
		position: absolute;
		width: 1px;
		height: 1px;
		overflow: hidden;
		clip-path: inset(50%);
		white-space: nowrap;
	}
}

/* ---------- Financiën (finance.js, Oct 2) ---------- */
.finance {
	display: grid;
	gap: 1rem;
}

/* The period: Maand / Kwartaal / Jaar, and ‹ oktober 2026 › */
.finance-period {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: .5rem;
}

.finance-kinds {
	display: flex;
	padding: .2rem;
	border-radius: 999px;
	background: var(--color-tile);
}

.finance-kinds label {
	cursor: pointer;
}

.finance-kinds input {
	position: absolute;
	opacity: 0;
	pointer-events: none;
}

.finance-kinds span {
	display: block;
	padding: .4rem .85rem;
	border-radius: 999px;
	font-size: .8125rem;
	font-weight: 600;
	color: var(--color-text-secondary);
	transition: background-color .2s ease-in-out, color .2s ease-in-out;
}

.finance-kinds input:checked + span {
	color: var(--color-text);
	background: var(--color-tile-item);
	box-shadow: 0 1px 3px #0000001a;
}

.finance-kinds input:focus-visible + span {
	outline: 2px solid var(--color-accent);
	outline-offset: 1px;
}

.finance-step {
	display: flex;
	align-items: center;
	gap: .25rem;
}

.finance-step button {
	display: grid;
	place-items: center;
	width: 2.1rem;
	height: 2.1rem;
	border-radius: 50%;
	color: var(--color-text);
	background: var(--color-tile);
}

.finance-step button:hover {
	background: var(--color-tile-separator);
}

.finance-step svg {
	width: 1.05rem;
	height: 1.05rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 2.2;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.finance-step-label {
	min-width: 8.5rem;
	font-size: .9375rem;
	font-weight: 600;
	text-align: center;
}

/* Four totals: two by two on a phone, one row when there is room */
.finance-tiles {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: .5rem;
}

@media (min-width: 52rem) {
	.finance-tiles {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

.finance-tile {
	display: flex;
	flex-direction: column;
	gap: .15rem;
	min-width: 0;
	padding: .8rem .9rem .85rem;
	border-radius: 1.15rem;
	corner-shape: squircle;
	background: var(--color-tile);
}

.finance-tile-label {
	font-size: .8125rem;
	font-weight: 600;
	color: var(--color-text-secondary);
}

.finance-tile-value {
	font-size: 1.6rem;
	font-weight: 700;
	line-height: 1.15;
	letter-spacing: -.02em;
	overflow-wrap: anywhere;
}

.finance-tile.is-negative .finance-tile-value,
.finance-balance.is-negative {
	color: var(--color-on-message-red);
}

.finance-tile-note {
	font-size: .75rem;
	line-height: 1.3;
	color: var(--color-text-secondary);
}

/* Per project (wide) and Nog te factureren side by side on a computer */
.finance-columns {
	display: grid;
	gap: 1rem;
	align-items: start;
}

@media (min-width: 64rem) {
	.finance-columns {
		grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
	}
}

.finance-card {
	min-width: 0;
	padding: .9rem .9rem 1rem;
	border-radius: 1.15rem;
	corner-shape: squircle;
	background: var(--color-tile);
}

.finance-card-title {
	display: flex;
	align-items: center;
	gap: .45rem;
	margin: 0 0 .6rem;
	font-size: 1rem;
	font-weight: 700;
}

.finance-count {
	padding: .05rem .5rem;
	border-radius: 999px;
	font-size: .75rem;
	color: var(--color-on-button-primary);
	background: var(--color-button-primary);
}

.finance-card-note {
	margin: -.35rem 0 .7rem;
	font-size: .8125rem;
	line-height: 1.35;
	color: var(--color-text-secondary);
}

.finance-empty {
	margin: 0;
	font-size: .875rem;
	color: var(--color-text-secondary);
}

/* The table: one line per project on a computer; on a phone the name on its own line
   and the five numbers under it, each with its name above it */
.finance-table {
	display: grid;
	gap: .3rem;
}

.finance-row {
	display: grid;
	grid-template-columns: minmax(0, 2.2fr) repeat(5, minmax(0, 1fr));
	align-items: center;
	gap: .5rem;
	width: 100%;
	padding: .55rem .7rem;
	border-radius: .8rem;
	font-size: .875rem;
	text-align: left;
	background: var(--color-tile-item);
}

.finance-row.is-link {
	cursor: pointer;
}

.finance-row.is-link:hover {
	background: var(--color-tile-item-hover);
}

.finance-row-name {
	display: grid;
	min-width: 0;
}

.finance-row-name b,
.finance-row-name small {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.finance-row-name small {
	font-size: .75rem;
	color: var(--color-text-secondary);
}

.finance-cell {
	font-variant-numeric: tabular-nums;
	text-align: right;
	white-space: nowrap;
}

.finance-balance {
	font-weight: 700;
}

.finance-head {
	padding-block: .2rem;
	font-size: .6875rem;
	font-weight: 700;
	letter-spacing: .04em;
	text-transform: uppercase;
	color: var(--color-text-secondary);
	background: none;
}

.finance-total {
	background: none;
	border-top: 2px solid var(--color-tile-separator);
	border-radius: 0;
	font-weight: 600;
}

@media (max-width: 40rem) {
	.finance-row {
		grid-template-columns: repeat(5, minmax(0, 1fr));
		row-gap: .35rem;
	}

	.finance-row-name {
		grid-column: 1 / -1;
	}

	.finance-head {
		display: none;
	}

	.finance-cell {
		display: grid;
		font-size: .8125rem;
		text-align: left;
	}

	.finance-row {
		column-gap: .45rem;
	}

	.finance-cell::before {
		content: attr(data-label);
		font-size: .625rem;
		font-weight: 600;
		letter-spacing: .02em;
		text-transform: uppercase;
		color: var(--color-text-secondary);
		overflow: hidden;
		text-overflow: ellipsis;
	}
}

/* Nog te factureren: per client, one thin row per uurbon */
.finance-group + .finance-group {
	margin-top: .75rem;
}

.finance-group-head span:last-child {
	text-transform: none;
}

.finance-group-head {
	display: flex;
	justify-content: space-between;
	gap: .5rem;
	margin: 0 .2rem .35rem;
	font-size: .75rem;
	font-weight: 700;
	letter-spacing: .04em;
	text-transform: uppercase;
	color: var(--color-text-secondary);
}

.finance-paper {
	display: flex;
	align-items: baseline;
	gap: .5rem;
	width: 100%;
	min-height: 2.4rem;
	padding: .5rem .5rem .5rem .75rem;
	border-radius: .8rem;
	font-size: .875rem;
	text-align: left;
	background: var(--color-tile-item);
	cursor: pointer;
}

.finance-paper + .finance-paper {
	margin-top: .3rem;
}

.finance-paper:hover {
	background: var(--color-tile-item-hover);
}

.finance-paper-week {
	font-weight: 700;
	white-space: nowrap;
}

.finance-paper-what {
	flex: 1;
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	color: var(--color-text-secondary);
}

.finance-paper-hours {
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

.finance-chevron {
	align-self: center;
	flex-shrink: 0;
	width: 1rem;
	height: 1rem;
	fill: none;
	stroke: var(--color-text-secondary);
	stroke-width: 2.2;
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* 320px phones: the five numbers a size smaller, so the widest (Turkish) still fit */
@media (max-width: 22.5rem) {
	.finance-cell {
		font-size: .75rem;
	}
}


/* ---------- A person's forms (forms.js, Oct 2) ---------- */
/* The Formulieren tile on a person's details: one white row per form, like the fields
   around it — an icon, the form's name, the date on it (or –) and a › to open it */
.form-links {
	display: flex;
	flex-direction: column;
	gap: .5rem;
}

.form-link {
	display: flex;
	align-items: center;
	gap: .6rem;
	min-height: 2.6rem;
	padding: .35rem .6rem .35rem .75rem;
	border: 1px solid transparent;
	border-radius: .6rem;
	corner-shape: squircle;
	font-size: .9rem;
	color: var(--color-text);
	text-decoration: none;
	background: var(--color-field);
	transition: border-color .15s ease-in-out;
}

.form-link:hover {
	border-color: color-mix(in srgb, var(--color-accent) 45%, transparent);
}

.form-link:focus-visible {
	outline: 0;
	border-color: var(--color-accent);
}

.form-link > svg {
	flex-shrink: 0;
	width: 1.25rem;
	height: 1.25rem;
	fill: none;
	stroke: var(--color-text-secondary);
	stroke-width: 1.7;
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* The name, and under it the date on the form (or –): the whole name always fits */
.form-link-text {
	display: flex;
	flex: 1;
	flex-direction: column;
	min-width: 0;
}

.form-link-name {
	overflow: hidden;
	font-weight: 500;
	line-height: 1.2rem;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.form-link-date {
	font-size: .78rem;
	line-height: 1.05rem;
	font-variant-numeric: tabular-nums;
	color: var(--color-text-secondary);
}

.form-link-chevron {
	display: grid;
	flex-shrink: 0;
	margin-left: -.2rem;
}

.form-link-chevron svg {
	width: 1.05rem;
	height: 1.05rem;
	fill: none;
	stroke: color-mix(in srgb, var(--color-text-secondary) 70%, transparent);
	stroke-width: 2.2;
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* The page of one form: Gebruikers › name › form. On a phone only ‹ name's form */
@media (max-width: 40rem) {
	.page-person-form .crumb-root,
	.page-person-form .crumb-root + .crumb-sep {
		display: none;
	}
}

.page-person-form .crumb-person {
	min-width: 0;
	max-width: 14rem;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* ---------- One form as paper (Oct 2, round 2) ---------- */
/* Two sheets side by side in the shape of an A4 (210 × 297), like the adviser's paper:
   the form's name top right in the brand colour over a line, numbered sections
   ("1  PERSOONSGEGEVENS") with their fields two by two, the company's own parts in a dashed
   box, and "Pagina 1 van 2" at the foot. On a computer each sheet fits the screen
   (forms.js splits a page that doesn't fit over more sheets, with page buttons); on a
   phone the pages are under each other. A narrow sheet has one column of fields.
   No coloured band along the top any more (round 3). The fields keep their own look (name small on top). */
#formpage-form {
	container: formpage / inline-size;
}

/* Under each other (a phone, a low window): as long as each needs */
.paper-sheets {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--tile-gap);
}

/* Fitting the screen (Oct 2, round 3): every sheet as high as the room, its width and
   height set by forms.js (A4), one or two side by side from the left, the page buttons
   on their right (Oct 2) */
.paper-sheets.is-fit {
	display: flex;
	align-items: flex-start;
	justify-content: flex-start;
	gap: var(--tile-gap);
}

/* The sheets fit the room by design: no scroll of a pixel from rounding */
.panel-body:has(> #formpage-form .paper-sheets.is-fit) {
	overflow-y: hidden;
}

.paper-sheets.is-fit .paper-sheet,
.paper-spacer {
	flex: none;
}

.paper-sheets.is-fit .paper-body {
	overflow: hidden;
}

.paper-sheets.is-fit .pfield-textarea {
	resize: none;
}

/* A low screen (a laptop): less margin and a smaller head, so more of the form fits
   on a sheet */
.paper-sheets.is-low .paper-sheet {
	gap: .75rem;
	padding: 1rem 1.25rem .7rem;
}

.paper-sheets.is-low .paper-body {
	gap: .8rem;
}

.paper-sheets.is-low .paper-head {
	padding-bottom: .45rem;
}

.paper-sheets.is-low .paper-title {
	font-size: 1.05rem;
}

.paper-sheets.is-low .paper-foot {
	padding-top: .4rem;
}

/* Next on top, back under it, right of the sheets: round grey buttons like the
   full screen button in the head (Oct 2: page numbers looked like a 2×2 of buttons) */
.paper-pager {
	display: flex;
	flex: none;
	flex-direction: column;
	gap: .5rem;
}

.paper-pager button {
	display: grid;
	place-items: center;
	width: 2.5rem;
	height: 2.5rem;
	border-radius: 50%;
	color: var(--color-panel-button-icon);
	background: var(--color-panel-button);
	transition: background-color .2s ease-in-out, opacity .2s ease-in-out;
}

.paper-pager button:hover:not(:disabled) {
	background: var(--color-panel-button-hover);
}

.paper-pager button:disabled {
	opacity: .4;
	cursor: default;
}

.paper-pager svg {
	width: 1.2rem;
	height: 1.2rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 2.2;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.paper-pager button:focus-visible {
	outline: 2px solid var(--color-accent);
	outline-offset: 1px;
}

.paper-sheet {
	container: sheet / inline-size;
	display: flex;
	flex-direction: column;
	gap: 1.1rem;
	min-width: 0;
	padding: 1.6rem 1.75rem 1rem;
	border-radius: 1.25rem;
	corner-shape: squircle;
	color: var(--color-text);
	background: var(--color-tile);
}

/* Everything between the head and the foot; on a fitted sheet what fits is decided
   by forms.js, row by row */
.paper-body {
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
	gap: 1.1rem;
	min-height: 0;
}

.paper-head {
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	gap: .1rem;
	padding-bottom: .7rem;
	border-bottom: 1px solid var(--color-tile-separator);
	text-align: right;
}

.paper-title {
	margin: 0;
	font-size: 1.35rem;
	font-weight: 750;
	line-height: 1.2;
	letter-spacing: .04em;
	text-transform: uppercase;
	overflow-wrap: anywhere;
	color: var(--color-accent);
}

.paper-sub {
	margin: 0;
	font-size: .85rem;
	color: var(--color-text-secondary);
}

.paper-intro {
	margin: 0;
	font-size: .8125rem;
	font-style: italic;
	line-height: 1.25rem;
	color: var(--color-text-secondary);
}

.paper-intro + .paper-intro {
	margin-top: -.6rem;
}

.paper-questions > .dba-question:first-child {
	border-top: 0;
}

.paper-section {
	display: flex;
	flex-direction: column;
	gap: .6rem;
}

.paper-section-title {
	display: flex;
	align-items: center;
	gap: .55rem;
	margin: 0;
	font-size: .78rem;
	font-weight: 700;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--color-accent);
}

.paper-nr {
	display: grid;
	flex-shrink: 0;
	place-items: center;
	width: 1.35rem;
	height: 1.35rem;
	border-radius: 50%;
	font-size: .75rem;
	letter-spacing: 0;
	color: #ffffff;
	background: var(--color-accent);
}

/* Two by two, like the paper; a text, a choice, a question or a signature the whole width */
.paper-fields {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	align-items: start;
	gap: .6rem .75rem;
}

/* (the :is() lifts it over the person pages' ".field + .field" spacing) */
#formpage-form :is(.paper-fields, .paper-stack) > :is(.field, .pfield, *) {
	min-width: 0;
	margin: 0;
}

.paper-wide {
	grid-column: 1 / -1;
}

.paper-fields .date-pill-field .field-label,
.form-choice .field-label {
	margin-left: .2rem;
}

/* The signing part: two stacks side by side (Plaats, Datum, Naam | Handtekening; or
   ZZP'er | Namens {company}) */
.paper-pair {
	display: grid;
	grid-column: 1 / -1;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	align-items: start;
	gap: .75rem 1.25rem;
	margin-top: .6rem;   /* a bit away from the declaration's text (Oct 2) */
}

/* A date in a white .pfield is that field like every other one (Oct 2: no
   pills): the same box as a text field (so exactly as high), its name in it, "2
   oktober 2026" as plain text where the typed value would be. On a form the name is
   small on top and the date under it; on a profile the name is on the left and the
   date on the right, like the fields around it. The whole field opens the wheels, and
   is lit like a field being typed in while they are open. */
.form-date {
	cursor: pointer;
}

.form-date:has(.date-pill-button[aria-expanded="true"]) {
	border-color: var(--color-accent);
}

/* Bare text: no room of its own around it (Oct 2), as high as its text. The
   text field's input is too: its 1.65rem is undone by flex: 1 in the column, so it is
   one line of text high (about 17px), and so is this */
:is(#profile-form, #person-form, #formpage-form) .form-date .date-pill {
	flex: 1;
	align-items: center;
	height: auto;
	margin: 0;
	padding: 0;
}

:is(#profile-form, #person-form, #formpage-form) .form-date .date-pill-button {
	position: static;
	justify-content: flex-start;
	width: 100%;
	height: auto;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	font-size: inherit;
	line-height: inherit;
	background: none;
}

:is(#profile-form, #person-form) .form-date .date-pill-button {
	justify-content: flex-end;
}

/* The whole field is the button */
.form-date .date-pill-button::before {
	content: "";
	position: absolute;
	inset: 0;
}

/* The pad is a white field like the others: its name small inside, top left (and
   Wissen top right), so its top is level with the field beside it */
#formpage-form .form-signature {
	position: relative;
}

#formpage-form .form-signature .signature-head {
	position: absolute;
	inset: 0 0 auto;
	z-index: 1;
	margin: 0;
	padding: .35rem .85rem 0;
	pointer-events: none;   /* signing goes on right under the name */
}

#formpage-form .form-signature .signature-label {
	font-size: .75rem;
	line-height: 1rem;
}

#formpage-form .form-signature .signature-clear {
	font-size: .75rem;
}

#formpage-form .form-signature .signature-pad {
	border-radius: .6rem;
	box-shadow: none;
}

.paper-stack {
	display: flex;
	flex-direction: column;
	gap: .6rem;
	min-width: 0;
}

/* The company's own parts: the paper's dashed box */
.paper-box {
	padding: .8rem 1rem 1rem;
	border: 1.5px dashed color-mix(in srgb, var(--color-text-secondary) 45%, transparent);
	border-radius: .8rem;
	corner-shape: squircle;
}

.paper-box .paper-section-title {
	font-size: .72rem;
	letter-spacing: .1em;
	color: var(--color-text-secondary);
}

.paper-foot {
	display: flex;
	justify-content: space-between;
	gap: 1rem;
	margin-top: auto;
	padding-top: .6rem;
	border-top: 1px solid var(--color-tile-separator);
	font-size: .75rem;
	color: var(--color-text-secondary);
}

/* The attachments: switches two by two, a line between the rows */
.paper-attach {
	gap: 0 1.5rem;
}

.paper-fields.paper-attach > .toggle-row {
	padding: .55rem 0;
	border-top: 1px solid var(--color-tile-separator);
}

.paper-fields.paper-attach > .toggle-row:nth-child(-n + 2) {
	padding-top: 0;
	border-top: 0;
}

/* Handed in: a round check instead of a switch (Oct 2). Empty: a white circle;
   ticked: the brand colour with a white checkmark */
.form-check {
	appearance: none;
	-webkit-appearance: none;
	flex-shrink: 0;
	display: grid;
	place-items: center;
	width: 1.5rem;
	height: 1.5rem;
	margin: 0;
	border: 1.5px solid color-mix(in srgb, var(--color-text-secondary) 45%, transparent);
	border-radius: 50%;
	background: var(--color-field);
	cursor: pointer;
	transition: background-color .15s ease-in-out, border-color .15s ease-in-out;
}

.form-check::after {
	content: "";
	width: .8rem;
	height: .8rem;
	background: #ffffff;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4.5 12.5 5 5 10-11'/%3E%3C/svg%3E") center / contain no-repeat;
	scale: 0;
	transition: scale .15s ease-in-out;
}

.form-check:checked {
	border-color: var(--color-accent);
	background: var(--color-accent);
}

.form-check:checked::after {
	scale: 1;
}

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

/* A form's own words (the declaration, a note) */
.form-text {
	margin: 0;
	font-size: .8125rem;
	line-height: 1.2rem;
	color: var(--color-text-secondary);
}

/* A few lines of text: the name on top, the text under it */
.pfield.pfield-area {
	flex-direction: column;
	align-items: stretch;
	gap: 0;
}

.pfield-textarea {
	height: auto;
	min-height: 3.6rem;
	resize: vertical;
	line-height: 1.3;
	text-align: left;
}

/* One of a few: the whole width */
.form-choice-switch {
	display: flex;
	flex-wrap: wrap;               /* a narrow phone: the last choice goes under */
	width: 100%;
	margin-top: .25rem;
}

.form-choice-switch .req-choice {
	flex: 1 1 auto;
	min-width: 0;
}

.form-choice-switch .req-choice span {
	overflow: hidden;
	padding-inline: .25rem;
	text-align: center;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* Wet DBA: the questions as the paper's table: number, question, Ja / Nee on the right,
   a bold line above each group (A. Gezag en werkwijze) */
.paper-questions {
	gap: 0;
}

#formpage-form .paper-fields > .paper-group {
	grid-column: 1 / -1;
	margin: .7rem 0 .15rem;
	font-size: .8125rem;
	font-weight: 650;
	color: var(--color-text);
}

#formpage-form .paper-fields > .paper-group:first-child {
	margin-top: 0;
}

.dba-question {
	display: grid;
	grid-template-columns: 1.1rem minmax(0, 1fr) auto;
	align-items: start;
	gap: .5rem;
	padding: .45rem 0;
	border-top: 1px solid var(--color-tile-separator);
}

.paper-group + .dba-question {
	border-top: 0;
}

.dba-nr {
	padding-top: .15rem;
	font-size: .75rem;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	color: var(--color-text-secondary);
}

.dba-text {
	font-size: .85rem;
	line-height: 1.25rem;
}

.dba-switch .req-choice span {
	min-width: 2.2rem;
	text-align: center;
}

/* Ja 12 · Nee 3 · Open 3, one quiet line in the company's box */
.dba-tally {
	display: flex;
	flex-wrap: wrap;
	gap: .2rem .5rem;
	margin: 0;
	font-size: .8125rem;
	color: var(--color-text-secondary);
}

.dba-tally b {
	font-weight: 650;
	font-variant-numeric: tabular-nums;
	color: var(--color-text);
}

/* The signature sits on the sheet itself, without the uurbon's grey band */
.form-signature {
	padding: 0;
	background: transparent;
}

.form-signature .signature-head {
	padding-inline: .2rem;
}

/* ZZP'er / Namens {company} above each side of the signing part */
.form-subhead {
	margin: 0 0 0 .2rem;
	font-size: .75rem;
	font-weight: 600;
	letter-spacing: .02em;
	text-transform: uppercase;
	color: var(--color-text-secondary);
}

/* On a form the values are long (an e-mail address, an IBAN with its name, a place
   and country of birth) and so are the paper's names for them: the name sits small on
   top inside the white field and the value under it, the whole width, so neither is
   cut off. Same white box as everywhere else. */
#formpage-form .pfield {
	flex-direction: column;
	align-items: stretch;
	gap: 0;
	padding: .35rem .85rem .2rem;
}

#formpage-form .pfield-label {
	max-width: none;
	font-size: .75rem;
	line-height: 1rem;
	white-space: normal;
	/* A tad lighter, so the name and what was typed don't look alike (Oct 2) */
	color: color-mix(in srgb, var(--color-text-secondary) 72%, var(--color-field));
}

#formpage-form .pfield-input {
	height: 1.65rem;
	text-align: left;
}

#formpage-form .pfield-textarea {
	height: auto;
	padding-top: .15rem;
}

#formpage-form :is(.dba-text, .toggle-row > span) {
	min-width: 0;
	overflow-wrap: break-word;
	hyphens: auto;
}

/* A narrow sheet: one column of fields (a fitted sheet is at least 27rem: two) */
@container sheet (max-width: 23rem) {
	.paper-fields,
	.paper-pair {
		grid-template-columns: minmax(0, 1fr);
	}

	.paper-fields.paper-attach > .toggle-row:nth-child(2) {
		padding-top: .55rem;
		border-top: 1px solid var(--color-tile-separator);
	}
}

/* A phone: less margin */
@container formpage (max-width: 40rem) {
	.paper-sheet {
		padding: 1.2rem 1rem 1rem;
	}

	.paper-title {
		font-size: 1.1rem;
	}
}

/* ---------- A person's details, more compact (Oct 2) ---------- */
/* Less white inside a field above and below its text (half: 2.15 → 1.55rem high,
   about 4px above and below the text), the sides 30 % narrower, the fields 20 % closer
   together. The title keeps its distance to the first field. The date pills, menus and
   certificate fields get the same lower height. The forms page keeps its own room. */
:is(#profile-form, #person-form) {
	--user-field-h: 1.55rem;
}

:is(#profile-form, #person-form) .pfield {
	min-height: 1.55rem;
}

:is(#profile-form, #person-form) :is(.pfield-input, .pfield .field-dropdown-button) {
	height: 1.4rem;
}

:is(#profile-form, #person-form) .pfield-value {
	padding-block: .2rem;
}

:is(#profile-form, #person-form) .tile {
	padding-inline: .7rem;
}


:is(#profile-form, #person-form) :is(.pfield + .pfield, .pfield + .field, .field + .pfield) {
	margin-top: .48rem;
}

/* A ZZP'er's company: the card and, in the same white box, the details as small
   "label  value" lines like under a choice on the uurbon */
.my-company-box {
	overflow: hidden;
	border-radius: .8rem;
	corner-shape: squircle;
	background: var(--color-tile-item);
}

.my-company-box .my-company-list .person-row {
	border-radius: 0;
	background: transparent;
}

.my-company-box .my-company-list .person-row:hover {
	background: var(--color-tile-item-hover);
}

.my-company-info {
	grid-template-columns: max-content minmax(0, 1fr);
	column-gap: .9rem;
	row-gap: .1rem;
	padding: .45rem .75rem .6rem;
	background: transparent;
}

.my-company-info::before {
	left: .75rem;
	right: .75rem;
}

.my-company-info > span:nth-child(odd) {
	color: var(--color-label-secondary);
}

.my-company-info > span:nth-child(even) {
	overflow-wrap: anywhere;
}

/* ---------- Putting a change back (users.js, Oct 2) ---------- */
/* A small round ↺ on a field that had something in it and now says something else:
   inside a field with its name in it, on the right after the value; under a name,
   right next to the name. Grey like the round buttons in a page's head. */
.field-revert {
	display: inline-grid;
	flex-shrink: 0;
	place-items: center;
	width: 1.35rem;
	height: 1.35rem;
	margin-left: -.35rem;   /* a bit nearer the value than the field's own gap */
	border-radius: 50%;
	vertical-align: middle;
	color: var(--color-panel-button-icon);
	background: var(--color-panel-button);
	transition: background-color .15s ease-in-out;
}

.field-label .field-revert {
	width: 1.1rem;
	height: 1.1rem;
	margin: -.1rem 0 0 .35rem;
}

.field-revert:hover {
	background: var(--color-panel-button-hover);
}

.field-revert svg {
	width: 72%;
	height: 72%;
	fill: none;
	stroke: currentColor;
	stroke-width: 2.4;
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* ---------- A person's Inloggen tile (users.js, Oct 21) ---------- */
/* Above Rechten: where the login stands (the same facts rows as elsewhere), the code
   just made in a box of its own, then the e-mail's language and the two buttons */
.person-login-facts {
	margin-bottom: .75rem;
}

.person-login-state-none { color: var(--color-text-secondary); }
.person-login-state-pending { color: var(--color-link); }
.person-login-state-expired { color: var(--color-destructive); }
.person-login-state-active { color: var(--color-success); }

.person-login-actions {
	display: grid;
	gap: .6rem;
}

.person-login-buttons {
	display: flex;
	flex-wrap: wrap;
	gap: .5rem;
}

.person-login-buttons .button {
	flex: 1 1 auto;
}

/* The code: big and spaced like in the e-mail, with a round copy button */
.person-login-code {
	margin-bottom: .75rem;
	padding: .7rem .85rem .75rem;
	border-radius: .75rem;
	corner-shape: squircle;
	background: var(--color-field);
}

.person-login-code-label {
	font-size: .75rem;
	font-weight: 600;
	color: var(--color-text-secondary);
}

.person-login-code-row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: .5rem;
}

.person-login-code-value {
	font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
	font-size: 1.5rem;
	font-weight: 700;
	letter-spacing: .08em;
	line-height: 2.2rem;
	user-select: all;
	overflow-wrap: anywhere;
}

.person-login-copy {
	display: grid;
	flex-shrink: 0;
	place-items: center;
	width: 2.25rem;
	height: 2.25rem;
	border-radius: 50%;
	color: var(--color-link);
	background: var(--color-tile);
	transition: background-color .15s ease-in-out;
}

.person-login-copy:hover {
	background: var(--color-fill);
}

.person-login-copy svg {
	width: 1.15rem;
	height: 1.15rem;
	stroke-width: 1.9;
}

.person-login-code-note {
	margin: .2rem 0 0;
	font-size: .8125rem;
	line-height: 1.15rem;
	color: var(--color-text-secondary);
}

.person-login-code-note.is-warning {
	color: var(--color-destructive);
}
