/* pms-core kit: tokens, base, type and components. No framework, no build step.

   Read docs/ui.md before using a class. The rules in short:
   - State is shape AND colour AND a word: use a state class (is-booked, is-hold, is-blocked, is-closed, is-free,
     is-problem, is-ok, is-cancelled) on an element that draws a shape, and give the word to screen readers.
   - No inline styles (the content security policy refuses them) and no colours outside the tokens below.
   - Logical properties only (margin-inline, padding-block, inset-inline-start), so right-to-left works.
   - The only shadow is under a sheet (and a dialog, which is a small sheet).

   The token blocks are read by pmscore/ui/colour.py and the tests: keep the marker comments. */

/* ---- fonts ----------------------------------------------------------------------------------------------------
   Atkinson Hyperlegible Next, SIL Open Font License 1.1 (fonts/OFL.txt). Self-hosted; the server rewrites these
   URLs to content-hashed names. Weights 400 and 700 only. */
@font-face {
  font-family: "Atkinson Hyperlegible Next";
  src: url("fonts/AtkinsonHyperlegibleNext-Regular.378aea0f5c1d.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Atkinson Hyperlegible Next";
  src: url("fonts/AtkinsonHyperlegibleNext-Bold.dda449f0f556.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* ---- tokens ---------------------------------------------------------------------------------------------------- */
:root {
  color-scheme: light dark;

  /* tokens:light */
  --paper: #FBFCFD;
  --surface: #FFFFFF;
  --sunk: #F1F4F7;
  --ink: #14202B;
  --muted: #566573;
  --line: #D9E0E6;
  --line-strong: #74818E;
  --primary: #1E6B52;
  --primary-hover: #17563F;
  --primary-tint: #E3F1EB;
  --primary-ink: #1E6B52;
  --on-primary: #FFFFFF;
  --focus: #1E6B52;
  --booked: #1D4E89;
  --booked-hover: #173F70;
  --on-booked: #FFFFFF;
  --hold: #B7791F;
  --hold-tint: #FFF4D6;
  --hold-ink: #8A5A12;
  --blocked: rgba(20, 32, 43, 0.55);
  --closed: #D9E0E6;
  --closed-ink: #14202B;
  --problem: #B4372A;
  --problem-tint: #FBE9E6;
  --problem-ink: #B4372A;
  --on-problem: #FFFFFF;
  --ok: #1E6B52;
  --ok-tint: #E4F2EC;
  --ok-ink: #1E6B52;
  --scrim: rgba(15, 23, 30, 0.48);
  --sheet-shadow: 0 -2px 6px rgba(15, 23, 30, 0.06), 0 12px 40px rgba(15, 23, 30, 0.22);
  /* end tokens */

  /* the hatch of a blocked night: a striped awning, 45 degrees */
  --hatch: repeating-linear-gradient(-45deg, var(--blocked) 0 2px, transparent 2px 7px);

  /* type: Atkinson Hyperlegible Next, then the system's own sans (Arabic, Hebrew and others come from it) */
  --font: "Atkinson Hyperlegible Next", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans",
    "Noto Sans Arabic", "Geeza Pro", Tahoma, "Helvetica Neue", Arial, sans-serif;
  --fs--1: 0.8333rem;  /* 13.3 px on phones: meta lines, chart prices */
  --fs-0: 1rem;        /* 16 px on phones, 17 px from 900 px */
  --fs-1: 1.2rem;
  --fs-2: 1.44rem;
  --fs-3: 1.728rem;
  --fs-4: 2.0736rem;
  --lh: 1.5;
  --lh-title: 1.2;

  /* space on a 4 px step; sizes in px so targets stay 44 px whatever the base */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-8: 32px;
  --sp-10: 40px;
  --sp-12: 48px;
  --gutter: 16px;
  --target: 44px;
  --control-h: 48px;
  --r-control: 6px;
  --r-sheet: 10px;
  --r-bar: 3px;
  --measure: 640px;
  --rail-w: 96px;
  --topbar-h: 56px;
  --tabbar-h: 60px;
  --chart-reserve: 220px;   /* the height above and below the chart on its page; an app may set its own */

  /* safe areas: notches, home indicators, folding phones. tools/shots.py overrides these to simulate a notch. */
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);
  --safe-right: env(safe-area-inset-right, 0px);

  /* the height of what the person can see; kit.js writes visualViewport.height here */
  --app-h: 100vh;

  --ease: cubic-bezier(0.2, 0, 0, 1);
  --t-sheet: 220ms;
  --t-fade: 160ms;
}
@supports (height: 100dvh) {
  :root { --app-h: 100dvh; }
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    /* tokens:dark */
    --paper: #0F171E;
    --surface: #16212A;
    --sunk: #121C24;
    --ink: #E6EDF2;
    --muted: #9DB0BF;
    --line: #2A3946;
    --line-strong: #6E7F8E;
    --primary: #237A5E;
    --primary-hover: #1D664F;
    --primary-tint: #173A2F;
    --primary-ink: #6FCFA8;
    --on-primary: #FFFFFF;
    --focus: #6FCFA8;
    --booked: #3B6FB6;
    --booked-hover: #335F9E;
    --on-booked: #FFFFFF;
    --hold: #E0A84A;
    --hold-tint: #2E2410;
    --hold-ink: #F3C877;
    --blocked: rgba(230, 237, 242, 0.55);
    --closed: #2A3946;
    --closed-ink: #E6EDF2;
    --problem: #C0402F;
    --problem-tint: #3A1D1A;
    --problem-ink: #FF8A7A;
    --on-problem: #FFFFFF;
    --ok: #237A5E;
    --ok-tint: #173A2F;
    --ok-ink: #6FCFA8;
    --scrim: rgba(0, 0, 0, 0.6);
    --sheet-shadow: 0 -2px 6px rgba(0, 0, 0, 0.3), 0 12px 40px rgba(0, 0, 0, 0.55);
    /* end tokens */
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  /* the same values as tokens:dark above; a test compares the two blocks */
  /* tokens:dark-forced */
  --paper: #0F171E;
  --surface: #16212A;
  --sunk: #121C24;
  --ink: #E6EDF2;
  --muted: #9DB0BF;
  --line: #2A3946;
  --line-strong: #6E7F8E;
  --primary: #237A5E;
  --primary-hover: #1D664F;
  --primary-tint: #173A2F;
  --primary-ink: #6FCFA8;
  --on-primary: #FFFFFF;
  --focus: #6FCFA8;
  --booked: #3B6FB6;
  --booked-hover: #335F9E;
  --on-booked: #FFFFFF;
  --hold: #E0A84A;
  --hold-tint: #2E2410;
  --hold-ink: #F3C877;
  --blocked: rgba(230, 237, 242, 0.55);
  --closed: #2A3946;
  --closed-ink: #E6EDF2;
  --problem: #C0402F;
  --problem-tint: #3A1D1A;
  --problem-ink: #FF8A7A;
  --on-problem: #FFFFFF;
  --ok: #237A5E;
  --ok-tint: #173A2F;
  --ok-ink: #6FCFA8;
  --scrim: rgba(0, 0, 0, 0.6);
  --sheet-shadow: 0 -2px 6px rgba(0, 0, 0, 0.3), 0 12px 40px rgba(0, 0, 0, 0.55);
  /* end tokens */
}
:root[data-theme="light"] { color-scheme: light; }

@media (min-width: 600px) {
  :root { --gutter: 24px; }
}
@media (min-width: 900px) {
  html { font-size: 106.25%; }
}
@media (min-width: 1200px) {
  :root { --gutter: 32px; }
}

/* ---- base ----------------------------------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html {
  font-size: 100%;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  background: var(--paper);
}
body {
  margin: 0;
  min-block-size: var(--app-h);
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--fs-0);
  font-weight: 400;
  line-height: var(--lh);
  font-variant-numeric: tabular-nums;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
  overflow-wrap: break-word;
}
h1, h2, h3, h4 { margin: 0; line-height: var(--lh-title); font-weight: 700; }
h1 { font-size: var(--fs-3); }
h2 { font-size: var(--fs-2); }
h3 { font-size: var(--fs-1); }
h4 { font-size: var(--fs-0); }
p { margin: 0; }
p + p { margin-block-start: var(--sp-3); }
b, strong { font-weight: 700; }
small { font-size: var(--fs--1); }
img, svg { max-inline-size: 100%; }
ul[role="list"], ol[role="list"] { list-style: none; margin: 0; padding: 0; }
a { color: var(--primary-ink); text-underline-offset: 0.18em; text-decoration-thickness: 1px; }
a:hover { text-decoration-thickness: 2px; }
code { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; font-size: 0.9em; }
hr { border: 0; border-block-start: 1px solid var(--line); margin: var(--sp-6) 0; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
:focus:not(:focus-visible) { outline: none; }
::selection { background: var(--primary-tint); color: var(--ink); }
[hidden] { display: none !important; }

/* visually hidden, still read by screen readers */
.vh {
  position: absolute !important;
  inline-size: 1px; block-size: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap;
}
/* a scroller holds its visually hidden texts, which would otherwise widen the page */
[data-scroller] { position: relative; }
.skip {
  position: absolute; inset-inline-start: var(--sp-2); inset-block-start: calc(var(--safe-top) + var(--sp-2));
  z-index: 100;
  min-block-size: var(--target); padding: var(--sp-3) var(--sp-4);
  background: var(--ink); color: var(--paper); border-radius: var(--r-control); font-weight: 700;
}
.skip:not(:focus) { inset-block-start: -200px; }

.icon {
  inline-size: 1.25em; block-size: 1.25em; flex: none;
  stroke: currentColor; fill: none; vertical-align: -0.25em;
}
.icon--lg { inline-size: 24px; block-size: 24px; }
[dir="rtl"] .icon--flip { transform: scaleX(-1); }

.num { font-variant-numeric: tabular-nums; white-space: nowrap; }
/* a phrase kept on one line where the line has room; it wraps inside itself only when it is wider than the line */
.keep { display: inline-block; max-inline-size: 100%; font-variant-numeric: tabular-nums; }
.muted { color: var(--muted); }
.small { font-size: var(--fs--1); }
.stack > * + * { margin-block-start: var(--sp-4); }
.stack-sm > * + * { margin-block-start: var(--sp-2); }
.stack-lg > * + * { margin-block-start: var(--sp-8); }
.cluster { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; }

/* ---- the app shell ---------------------------------------------------------------------------------------------
   Phones: top bar, content, bottom tab bar. From 900 px: the tab bar becomes a left rail. */
.app {
  min-block-size: var(--app-h);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto 1fr auto;
  grid-template-areas: "top" "main" "nav";
}
.app > .topbar { grid-area: top; }
.app > .tabbar { grid-area: nav; }
.app > .main { grid-area: main; min-inline-size: 0; }
.app--bare { grid-template-rows: auto 1fr; grid-template-areas: "top" "main"; }

.main {
  padding-block: var(--sp-4) var(--sp-8);
  padding-inline: calc(var(--gutter) + var(--safe-left)) calc(var(--gutter) + var(--safe-right));
}
[dir="rtl"] .main {
  padding-inline: calc(var(--gutter) + var(--safe-right)) calc(var(--gutter) + var(--safe-left));
}
.content { max-inline-size: var(--measure); margin-inline: auto; }
.content--wide { max-inline-size: 1200px; }
.content--full { max-inline-size: none; }   /* the chart: every pixel of width is another night */
.full { margin-inline: calc(-1 * var(--gutter)); }

/* top bar */
.topbar {
  position: sticky; inset-block-start: 0; z-index: 20;
  display: flex; align-items: center; gap: var(--sp-1);
  min-block-size: calc(var(--topbar-h) + var(--safe-top));
  padding-block-start: var(--safe-top);
  padding-inline: calc(var(--sp-1) + var(--safe-left)) calc(var(--sp-1) + var(--safe-right));
  background: var(--surface);
  border-block-end: 1px solid var(--line);
}
.topbar__brand {
  display: flex; align-items: center; gap: var(--sp-2);
  min-block-size: var(--target); padding-inline: var(--sp-3); padding-block: var(--sp-2);
  color: var(--ink); text-decoration: none; font-weight: 700; min-inline-size: 0; line-height: var(--lh-title);
}
.topbar__brand img { block-size: 28px; inline-size: auto; max-inline-size: 140px; object-fit: contain; }
.topbar__title {
  flex: 1; min-inline-size: 0; margin: 0; padding-inline: var(--sp-2);
  font-size: var(--fs-1); font-weight: 700; line-height: var(--lh-title);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.topbar__brand + .topbar__title { padding-inline-start: 0; }
.topbar__actions { display: flex; align-items: center; gap: var(--sp-1); margin-inline-start: auto; }

/* bottom tab bar on phones, left rail from 900 px. At most five items; labels always shown. */
.tabbar {
  position: sticky; inset-block-end: 0; z-index: 20;
  display: flex; align-items: stretch;
  padding-block-end: var(--safe-bottom);
  padding-inline: var(--safe-left) var(--safe-right);
  background: var(--surface);
  border-block-start: 1px solid var(--line);
}
.tabbar__item {
  position: relative; flex: 1 1 0; min-inline-size: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  min-block-size: var(--tabbar-h); padding: var(--sp-1) 2px;
  color: var(--muted); text-decoration: none;
  font-size: 0.75rem; line-height: 1.15; text-align: center;
}
.tabbar__item .icon { inline-size: 24px; block-size: 24px; }
.tabbar__label {
  max-inline-size: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tabbar__item[aria-current="page"] { color: var(--primary-ink); font-weight: 700; }
/* the selected tab carries a short bar, the kit's mark of "this one" */
.tabbar__item[aria-current="page"]::before {
  content: ""; position: absolute; inset-block-start: 0; inset-inline: 50%;
  inline-size: 32px; margin-inline-start: -16px; block-size: 3px;
  background: var(--primary); border-radius: 0 0 var(--r-bar) var(--r-bar);
}
.tabbar__item:hover { color: var(--ink); }
.tabbar__item[aria-current="page"]:hover { color: var(--primary-ink); }

@media (min-width: 900px) {
  .app {
    grid-template-columns: calc(var(--rail-w) + var(--safe-left)) minmax(0, 1fr);
    grid-template-rows: auto 1fr;
    grid-template-areas: "nav top" "nav main";
  }
  /* the rail's surface and edge run the page's full height; the rail itself sticks */
  .app:not(.app--bare) {
    background-image: linear-gradient(var(--line), var(--line)), linear-gradient(var(--surface), var(--surface));
    background-repeat: no-repeat;
    background-size: 1px 100%, calc(var(--rail-w) + var(--safe-left)) 100%;
    background-position: left calc(var(--rail-w) + var(--safe-left) - 1px) top 0, left 0 top 0;
  }
  .app--bare { grid-template-columns: minmax(0, 1fr); grid-template-areas: "top" "main"; }
  [dir="rtl"] .app:not(.app--bare) {
    grid-template-columns: calc(var(--rail-w) + var(--safe-right)) minmax(0, 1fr);
    background-size: 1px 100%, calc(var(--rail-w) + var(--safe-right)) 100%;
    background-position: right calc(var(--rail-w) + var(--safe-right) - 1px) top 0, right 0 top 0;
  }
  .tabbar {
    inset-block: 0 auto;
    flex-direction: column; justify-content: flex-start; gap: var(--sp-1);
    block-size: var(--app-h);
    padding-block: calc(var(--safe-top) + var(--sp-3)) var(--sp-3);
    padding-inline: var(--safe-left) 0;
    border-block-start: 0; border-inline-end: 1px solid var(--line);
  }
  [dir="rtl"] .tabbar { padding-inline: var(--safe-right) 0; }
  .tabbar__item { flex: none; min-block-size: 64px; padding-inline: var(--sp-1); }
  .tabbar__label { white-space: normal; overflow-wrap: anywhere; }
  .tabbar__item[aria-current="page"]::before {
    inset-block: 50% auto; inset-inline: 0 auto;
    inline-size: 3px; block-size: 32px; margin: -16px 0 0;
    border-radius: 0 var(--r-bar) var(--r-bar) 0;
  }
  [dir="rtl"] .tabbar__item[aria-current="page"]::before { border-radius: var(--r-bar) 0 0 var(--r-bar); }
  .main { padding-block-start: var(--sp-6); }
}

/* page header */
.page-head {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--sp-3) var(--sp-4);
  margin-block-end: var(--sp-5);
}
.page-head__text { flex: 1 1 16rem; min-inline-size: 0; }
.page-head__sub { margin-block-start: var(--sp-1); color: var(--muted); }
.page-head__actions { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
@media (min-width: 900px) { .page-head h1 { font-size: var(--fs-4); } }

.section { margin-block-start: var(--sp-10); }
.section > h2 { margin-block-end: var(--sp-4); }
.section__head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: var(--sp-2); margin-block-end: var(--sp-3); }
.section__head h2, .section__head h3 { margin: 0; }

/* list and detail side by side from 900 px */
.split { display: grid; gap: 0; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 900px) {
  .split {
    grid-template-columns: minmax(300px, 380px) minmax(0, 1fr);
    border: 1px solid var(--line); border-radius: var(--r-sheet); background: var(--surface);
    overflow: hidden;
  }
  .split__list { border-inline-end: 1px solid var(--line); min-inline-size: 0; }
  .split__detail { min-inline-size: 0; padding: var(--sp-6); }
}
@media (max-width: 899.98px) {
  .split--detail .split__list { display: none; }
  .split--list .split__detail { display: none; }
}

/* ---- the state shapes ------------------------------------------------------------------------------------------
   One definition per state; every component that draws a state (a bar, a mark, a cell, a band, a step) reads
   these four properties. Free is empty. */
.is-booked { --shape-bg: var(--booked); --shape-edge: var(--booked); --shape-ink: var(--on-booked); }
.is-hold { --shape-bg: var(--hold-tint); --shape-edge: var(--hold); --shape-ink: var(--hold-ink); }
.is-blocked { --shape-bg: var(--hatch), var(--surface); --shape-edge: var(--blocked); --shape-ink: var(--ink); }
.is-closed { --shape-bg: var(--closed); --shape-edge: var(--closed); --shape-ink: var(--closed-ink); }
.is-free { --shape-bg: transparent; --shape-edge: var(--line-strong); --shape-ink: var(--ink); }
.is-problem { --shape-bg: var(--problem); --shape-edge: var(--problem); --shape-ink: var(--on-problem); }
.is-ok { --shape-bg: var(--ok); --shape-edge: var(--ok); --shape-ink: var(--on-primary); }
.is-cancelled { --shape-bg: transparent; --shape-edge: var(--muted); --shape-ink: var(--muted); }

.shape {
  display: inline-block; flex: none;
  inline-size: 20px; block-size: 8px;
  background: var(--shape-bg, transparent);
  border: 2px solid var(--shape-edge, var(--line-strong));
  border-radius: var(--r-bar);
}
.shape.is-free { border-style: dashed; border-width: 1px; }
.shape.is-cancelled { border-style: dashed; }
.shape.is-blocked { border-width: 1px; }

/* the badge-less state mark: a short bar and its word */
.mark {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs--1); line-height: 1.3; color: var(--ink); white-space: nowrap;
}
.mark.is-hold { color: var(--hold-ink); }
.mark.is-problem { color: var(--problem-ink); }
.mark.is-ok { color: var(--ok-ink); }
.mark.is-cancelled { color: var(--muted); }

.legend { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-5); padding: 0; margin: 0; list-style: none; }
.legend .shape { inline-size: 28px; block-size: 14px; }
.legend li { display: inline-flex; align-items: center; gap: var(--sp-2); font-size: var(--fs--1); }

/* ---- buttons --------------------------------------------------------------------------------------------------- */
.btn {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-block-size: var(--target); min-inline-size: var(--target);
  padding: var(--sp-2) var(--sp-4);
  border: 1px solid var(--line-strong); border-radius: var(--r-control);
  background: var(--surface); color: var(--ink);
  font: inherit; font-weight: 700; line-height: 1.2; text-align: center; text-decoration: none;
  cursor: pointer; user-select: none;
}
.btn:hover { background: var(--sunk); }
.btn--primary { background: var(--primary); border-color: var(--primary); color: var(--on-primary); }
.btn--primary:hover { background: var(--primary-hover); border-color: var(--primary-hover); }
.btn--danger { background: var(--problem); border-color: var(--problem); color: var(--on-problem); }
.btn--danger:hover { background: var(--problem); filter: brightness(0.92); }
.btn--quiet { background: transparent; border-color: transparent; color: var(--primary-ink); }
.btn--quiet:hover { background: var(--primary-tint); }
.btn--block { display: flex; inline-size: 100%; }
/* cleaners and guests: a big, unmissable target */
.btn--large { min-block-size: 56px; padding-inline: var(--sp-6); font-size: var(--fs-1); }
.btn[disabled], .btn[aria-disabled="true"] {
  cursor: not-allowed; background: var(--sunk); border-color: var(--line); color: var(--muted); filter: none;
}
.btn[aria-busy="true"] { cursor: progress; }
.btn[aria-busy="true"] > :not(.btn__spinner) { visibility: hidden; }
.btn__spinner {
  position: absolute; inset: 0; margin: auto;
  inline-size: 20px; block-size: 20px;
  border: 2px solid currentColor; border-inline-end-color: transparent; border-radius: 50%;
  animation: kit-spin 0.8s linear infinite;
}
.btn:not([aria-busy="true"]) > .btn__spinner { display: none; }
@keyframes kit-spin { to { transform: rotate(360deg); } }

.iconbtn {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  inline-size: var(--target); block-size: var(--target);
  border: 0; border-radius: var(--r-control); background: transparent; color: var(--ink);
  cursor: pointer; text-decoration: none;
}
.iconbtn:hover { background: var(--sunk); }
.iconbtn .icon { inline-size: 24px; block-size: 24px; }
.actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: center; }
.actions--end { justify-content: flex-end; }

/* ---- fields: label above, hint and error below ----------------------------------------------------------------- */
.field { display: flex; flex-direction: column; gap: var(--sp-1); min-inline-size: 0; }
.field + .field, .field + .choices, .choices + .field, .choices + .choices { margin-block-start: var(--sp-5); }
.field__label { font-weight: 700; }
.field__label .muted { font-weight: 400; }
.field__hint { font-size: var(--fs--1); color: var(--muted); }
.field__error {
  display: flex; gap: var(--sp-2); align-items: flex-start;
  font-size: var(--fs--1); color: var(--problem-ink); font-weight: 700;
}
.field__error .icon { margin-block-start: 0.1em; }
.input, .select, .textarea {
  display: block; inline-size: 100%; min-inline-size: 0;
  min-block-size: var(--control-h);
  padding: var(--sp-3);
  border: 1px solid var(--line-strong); border-radius: var(--r-control);
  background: var(--surface); color: var(--ink);
  font: inherit; font-size: max(16px, 1rem); line-height: 1.4;
}
.input::placeholder, .textarea::placeholder { color: var(--muted); opacity: 1; }
.input:hover, .select:hover, .textarea:hover { border-color: var(--ink); }
.input:focus-visible, .select:focus-visible, .textarea:focus-visible { outline-offset: 0; border-color: var(--focus); }
.input[aria-invalid="true"], .select[aria-invalid="true"], .textarea[aria-invalid="true"] {
  border: 2px solid var(--problem); padding: calc(var(--sp-3) - 1px);
}
.input:disabled, .select:disabled, .textarea:disabled {
  background: var(--sunk); border-color: var(--line); color: var(--muted); cursor: not-allowed;
}
.input--num { text-align: end; font-variant-numeric: tabular-nums; }
.input[type="date"], .input[type="time"] { appearance: none; -webkit-appearance: none; }
.input[type="date"]::-webkit-date-and-time-value { text-align: start; }
/* a time is hours and minutes, never seconds (kit.js timeFields sets the minute step too) */
input[type="time"]::-webkit-datetime-edit-second-field, input[type="time"]::-webkit-datetime-edit-millisecond-field {
  display: none;
}
.textarea { min-block-size: 112px; resize: vertical; }
.select {
  appearance: none; -webkit-appearance: none;
  padding-inline-end: var(--sp-10);
  background-image: linear-gradient(45deg, transparent 50%, var(--ink) 50%), linear-gradient(-45deg, transparent 50%, var(--ink) 50%);
  background-size: 6px 6px, 6px 6px;
  background-position: right 20px center, right 14px center;
  background-repeat: no-repeat;
}
[dir="rtl"] .select { background-position: left 14px center, left 20px center; }
.search { position: relative; }
.search .icon { position: absolute; inset-inline-start: var(--sp-3); inset-block-start: 50%; margin-block-start: -0.625em;
  color: var(--muted); pointer-events: none; }
.search .input { padding-inline-start: var(--sp-10); }
.input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; }

/* two short fields side by side when there is room */
.field-row { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-5) var(--sp-4); }
.field-row > .field { margin: 0; }
.field-row + .field, .field + .field-row, .field-row + .field-row { margin-block-start: var(--sp-5); }
@media (min-width: 480px) { .field-row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* checkbox, radio, switch: the whole row is the 44 px target */
.choices { border: 0; margin: 0; padding: 0; min-inline-size: 0; }
.choices > legend { padding: 0; margin-block-end: var(--sp-1); font-weight: 700; }
.choice {
  display: flex; align-items: center; gap: var(--sp-3);
  min-block-size: var(--target); padding-block: var(--sp-1);
  cursor: pointer;
}
.choice__text { flex: 1; min-inline-size: 0; }
.choice__text .field__hint { display: block; }
.check, .radio {
  appearance: none; -webkit-appearance: none; flex: none; margin: 0;
  inline-size: 24px; block-size: 24px;
  border: 2px solid var(--line-strong); background: var(--surface);
  display: inline-grid; place-content: center; cursor: pointer;
}
.check { border-radius: var(--r-bar); }
.radio { border-radius: 50%; }
.check::before {
  content: ""; inline-size: 12px; block-size: 7px; margin-block-start: -3px;
  border: solid var(--on-primary); border-width: 0 0 3px 3px; transform: rotate(-45deg) scale(0);
}
.radio::before { content: ""; inline-size: 10px; block-size: 10px; border-radius: 50%; background: var(--primary); transform: scale(0); }
.check:checked { background: var(--primary); border-color: var(--primary); }
.check:checked::before, .radio:checked::before { transform: rotate(-45deg) scale(1); }
.radio:checked::before { transform: scale(1); }
.radio:checked { border-color: var(--primary); }
.check:disabled, .radio:disabled { border-color: var(--line); background: var(--sunk); cursor: not-allowed; }
.check[aria-invalid="true"], .radio[aria-invalid="true"] { border-color: var(--problem); }

.switch {
  appearance: none; -webkit-appearance: none; flex: none; margin: 0; cursor: pointer;
  position: relative; inline-size: 52px; block-size: 32px; border-radius: 16px;
  background: var(--surface); border: 2px solid var(--line-strong);
}
.switch::before {
  content: ""; position: absolute; inset-block-start: 4px; inset-inline-start: 4px;
  inline-size: 20px; block-size: 20px; border-radius: 50%; background: var(--line-strong);
}
.switch:checked { background: var(--primary); border-color: var(--primary); }
.switch:checked::before { inset-inline-start: 24px; background: var(--on-primary); }
.switch:disabled { opacity: 0.5; cursor: not-allowed; }

/* segmented control: a radio group as joined buttons */
.segmented {
  display: inline-flex; max-inline-size: 100%; min-inline-size: 0;
  border: 1px solid var(--line-strong); border-radius: var(--r-control); background: var(--surface);
  padding: 2px; gap: 2px; border-width: 1px; margin: 0;
}
fieldset.segmented { min-inline-size: 0; }
.segmented--block { display: flex; inline-size: 100%; }
.segmented__item { position: relative; flex: 1 1 auto; display: flex; min-inline-size: 0; }
.segmented__item input { position: absolute; opacity: 0; inset: 0; margin: 0; inline-size: 100%; block-size: 100%; cursor: pointer; }
.segmented__item span {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: var(--sp-1);
  min-block-size: var(--target); padding: var(--sp-1) var(--sp-3);
  border-radius: 4px; font-weight: 700; color: var(--muted); text-align: center; line-height: 1.2;
}
.segmented__item input:checked + span { background: var(--primary); color: var(--on-primary); }
.segmented__item input:focus-visible + span { outline: 3px solid var(--focus); outline-offset: 1px; }
.segmented__item:hover input:not(:checked) + span { color: var(--ink); background: var(--sunk); }

/* filter chips */
.chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.chips--scroll { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; padding-block: 2px;
  margin-inline: calc(-1 * var(--gutter)); padding-inline: var(--gutter); }
.chips--scroll::-webkit-scrollbar { display: none; }
.chip {
  display: inline-flex; align-items: center; gap: var(--sp-2); flex: none;
  min-block-size: var(--target); padding: var(--sp-1) var(--sp-4);
  border: 1px solid var(--line-strong); border-radius: var(--r-control);
  background: var(--surface); color: var(--ink); font: inherit; cursor: pointer; text-decoration: none;
}
.chip:hover { background: var(--sunk); }
.chip[aria-pressed="true"], .chip[aria-current] {
  background: var(--primary-tint); border-color: var(--primary); color: var(--primary-ink); font-weight: 700;
}
.chip .chip__count { color: var(--muted); font-weight: 400; }
.chip .icon { inline-size: 18px; block-size: 18px; }
.chip:not([aria-pressed="true"]) .chip__check { display: none; }

/* notices: a bar on the leading edge, like a list row */
.notice {
  display: flex; gap: var(--sp-3); align-items: flex-start;
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-control); background: var(--sunk);
  border-inline-start: 6px solid var(--line-strong);
}
.notice.is-problem { background: var(--problem-tint); border-inline-start-color: var(--problem); }
.notice.is-hold { background: var(--hold-tint); border-inline-start-color: var(--hold); }
.notice.is-ok { background: var(--ok-tint); border-inline-start-color: var(--ok); }
.notice > .icon { margin-block-start: 0.15em; }
.notice.is-problem > .icon { color: var(--problem-ink); }
.notice.is-hold > .icon { color: var(--hold-ink); }
.notice.is-ok > .icon { color: var(--ok-ink); }
.notice__title { font-weight: 700; }

/* ---- lists: rows with hairlines, a state bar on the leading edge ---------------------------------------------- */
.list { list-style: none; margin: 0; padding: 0; border-block-start: 1px solid var(--line); background: var(--surface); }
.list--flush { border-block-start: 0; }
.list > li { border-block-end: 1px solid var(--line); }
.row {
  position: relative;
  display: flex; align-items: center; gap: var(--sp-3);
  min-block-size: 64px; padding: var(--sp-3) var(--sp-3) var(--sp-3) var(--sp-4);
  color: var(--ink); text-decoration: none;
}
a.row:hover, button.row:hover { background: var(--sunk); }
button.row { inline-size: 100%; border: 0; background: none; font: inherit; text-align: start; cursor: pointer; }
.row[aria-current], .row.is-selected { background: var(--primary-tint); }
.row__bar {
  align-self: stretch; flex: none; inline-size: 6px; min-block-size: 32px;
  background: var(--shape-bg, transparent);
  border: 2px solid var(--shape-edge, transparent);
  border-radius: var(--r-bar);
}
.row__bar.is-free { border-style: dashed; border-width: 1px; }
.row__bar.is-cancelled { border-style: dashed; }
.row__bar.is-blocked { border-width: 1px; }
.row__main { flex: 1 1 auto; min-inline-size: 0; display: flex; flex-direction: column; gap: 2px; }
.row__title { font-weight: 700; line-height: 1.3; }
.row__meta { font-size: var(--fs--1); color: var(--muted); line-height: 1.35; }
.row__meta > * + *::before { content: " · "; }
.row__end { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: var(--sp-1); text-align: end; max-inline-size: 45%; }
.row__amount { font-weight: 700; white-space: nowrap; }
.row__chev { flex: none; color: var(--muted); }
[dir="rtl"] .row__chev { transform: scaleX(-1); }
/* row--wrap: on narrow phones the amount and the mark go under the title, the bar runs the full height */
@media (max-width: 479.98px) {
  .row--wrap {
    display: grid; align-items: center;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas: "bar main chev" "bar end chev";
    gap: var(--sp-2) var(--sp-3);
  }
  .row--wrap > .row__bar { grid-area: bar; }
  .row--wrap > .row__main { grid-area: main; }
  .row--wrap > .row__end { grid-area: end; flex-direction: row; flex-wrap: wrap; align-items: center;
    justify-content: space-between; max-inline-size: none; text-align: start; }
  .row--wrap > .row__chev { grid-area: chev; }
}

/* the cleaner's row: big target, few words */
.row--task { min-block-size: 80px; gap: var(--sp-4); }
.row--task .row__title { font-size: var(--fs-1); }
.row--task .row__bar { inline-size: 8px; }

.list-head { font-size: var(--fs-1); margin-block: var(--sp-6) var(--sp-3); }
.row--task .task__btn { flex: none; inline-size: 64px; min-inline-size: 64px; padding: 0; }
.row--task .task__btn .icon { inline-size: 28px; block-size: 28px; }
.row--task .task__done { flex: none; inline-size: 64px; display: grid; place-items: center; color: var(--ok-ink); }
.row--task .row__main { gap: var(--sp-1); }

.load-more { display: flex; flex-direction: column; align-items: center; gap: var(--sp-2); padding: var(--sp-5) 0; }

/* empty and error states */
.state {
  display: flex; flex-direction: column; align-items: center; text-align: center; gap: var(--sp-3);
  padding: var(--sp-10) var(--sp-4); max-inline-size: 28rem; margin-inline: auto;
}
.state__art { display: flex; flex-direction: column; gap: 6px; inline-size: 120px; margin-block-end: var(--sp-2); }
.state__art span { block-size: 14px; border-radius: var(--r-bar); border: 2px dashed var(--line-strong); }
.state__art span:nth-child(2) { inline-size: 70%; margin-inline-start: 18%; }
.state__art span:nth-child(3) { inline-size: 45%; }
.state__art--problem span { border: 0; background: var(--problem); }
.state__art--problem span:nth-child(2) { background: var(--hatch), var(--problem-tint); }
.state__art--problem span:nth-child(3) { background: var(--problem-tint); border: 2px solid var(--problem); }
.state h2, .state h3 { font-size: var(--fs-1); }
.state p { color: var(--muted); }

/* skeleton: still, nothing moves */
.skeleton { display: block; background: var(--sunk); border-radius: var(--r-bar); block-size: 1em; }
.skeleton--title { inline-size: 55%; block-size: 1.1em; }
.skeleton--meta { inline-size: 80%; block-size: 0.8em; margin-block-start: var(--sp-2); }
.skeleton--bar { inline-size: 6px; align-self: stretch; block-size: auto; min-block-size: 32px; }
.skeleton--amount { inline-size: 4.5em; }

/* the money line: label left, tabular amount right */
.money { margin: 0; }
.money__line {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-4);
  padding-block: var(--sp-2);
}
.money__line + .money__line { border-block-start: 1px solid var(--line); }
.money__line dt { min-inline-size: 0; }
.money__line dd { margin: 0; font-variant-numeric: tabular-nums; white-space: nowrap; text-align: end; }
.money__line--sub dt { color: var(--muted); padding-inline-start: var(--sp-4); }
.money__line--total { border-block-start: 2px solid var(--ink) !important; font-weight: 700; font-size: var(--fs-1); }
.money__line--due dd { color: var(--problem-ink); font-weight: 700; }
.money__line--paid dd { color: var(--ok-ink); }
.money__note { font-size: var(--fs--1); color: var(--muted); }

/* key facts: a two-column description list */
.facts { display: grid; grid-template-columns: minmax(0, max-content) minmax(0, 1fr); gap: var(--sp-2) var(--sp-4); margin: 0; }
.facts dt { color: var(--muted); }
.facts dd { margin: 0; min-inline-size: 0; }

.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-sheet); padding: var(--sp-4); }
@media (min-width: 600px) { .card { padding: var(--sp-6); } }

/* ---- the message thread ------------------------------------------------------------------------------------------ */
.thread { list-style: none; margin: 0; padding: var(--sp-4) 0; display: flex; flex-direction: column; gap: var(--sp-3); }
.thread__day { align-self: center; font-size: var(--fs--1); color: var(--muted); padding-block: var(--sp-2); }
.msg { max-inline-size: min(85%, 34rem); display: flex; flex-direction: column; gap: var(--sp-1); }
.msg__body {
  padding: var(--sp-3) var(--sp-4); border-radius: var(--r-sheet);
  white-space: pre-wrap; overflow-wrap: anywhere;
}
.msg__meta { display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-2); align-items: center; font-size: var(--fs--1); color: var(--muted); }
.msg__meta .icon { inline-size: 16px; block-size: 16px; }
.msg--in { align-self: flex-start; }
.msg--in .msg__body { background: var(--surface); border: 1px solid var(--line); border-end-start-radius: var(--r-bar); }
.msg--out { align-self: flex-end; align-items: flex-end; }
.msg--out .msg__body { background: var(--primary-tint); color: var(--ink); border-end-end-radius: var(--r-bar); }
.msg--note { align-self: stretch; max-inline-size: none; }
.msg--note .msg__body { background: var(--sunk); border: 2px dashed var(--line-strong); }
.msg__kind { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--fs--1); font-weight: 700; color: var(--muted); }
.msg.is-failed .msg__body { border: 2px solid var(--problem); }
.msg.is-failed .msg__meta { color: var(--problem-ink); font-weight: 700; }
.msg.is-queued .msg__body { opacity: 0.85; }
.msg__retry { min-block-size: var(--target); padding-inline: var(--sp-3); }

.thread-head { padding-block-end: var(--sp-3); border-block-end: 1px solid var(--line); }
.thread-head h2 { font-size: var(--fs-1); }
.split__search { padding: var(--sp-3); border-block-end: 1px solid var(--line); }
@media (max-width: 899.98px) { .split__search { padding-inline: 0; } }

.composer {
  position: sticky; inset-block-end: 0;
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--sp-2) var(--sp-2); align-items: end;
  padding: var(--sp-3) 0 calc(var(--sp-3));
  background: var(--composer-bg, var(--paper)); border-block-start: 1px solid var(--line);
}
@media (min-width: 900px) { .split__detail { --composer-bg: var(--surface); } }
.app > .main .composer { inset-block-end: calc(var(--tabbar-h) + var(--safe-bottom)); }
@media (min-width: 900px) { .app > .main .composer { inset-block-end: 0; } }
.composer__kind { grid-column: 1 / -1; }
.composer__input {
  min-block-size: var(--control-h); max-block-size: calc(var(--app-h) * 0.4);
  resize: none; overflow-y: auto; field-sizing: content;
}
.composer__send { min-block-size: var(--control-h); min-inline-size: var(--control-h); padding-inline: var(--sp-3); }
[dir="rtl"] .composer__send .icon { transform: scaleX(-1); }

/* ---- the stepper: steps drawn as a short chart row ------------------------------------------------------------- */
.stepper { margin-block-end: var(--sp-6); }
.stepper__now { font-size: var(--fs--1); color: var(--muted); margin-block-end: var(--sp-2); }
.stepper__now b { color: var(--ink); }
.stepper ol { list-style: none; margin: 0; padding: 0; display: flex; gap: var(--sp-1); }
.stepper li { flex: 1 1 0; min-inline-size: 0; display: flex; flex-direction: column; gap: var(--sp-2); }
.stepper__bar {
  display: block; block-size: 10px; border-radius: var(--r-bar);
  background: var(--closed); border: 2px solid var(--closed);
}
.stepper li.is-done .stepper__bar { background: var(--primary); border-color: var(--primary); }
.stepper li[aria-current="step"] .stepper__bar { background: var(--primary-tint); border-color: var(--primary); }
.stepper__label { font-size: var(--fs--1); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stepper li[aria-current="step"] .stepper__label { color: var(--ink); font-weight: 700; }
@media (max-width: 599.98px) { .stepper__label { position: absolute !important; inline-size: 1px; block-size: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } }

/* the signature pad frame */
.signature {
  position: relative; display: block; inline-size: 100%;
  border: 1px solid var(--line-strong); border-radius: var(--r-control); background: var(--surface);
  aspect-ratio: 5 / 2; min-block-size: 160px; touch-action: none;
}
.signature__pad { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; border-radius: inherit; cursor: crosshair; }
.signature__line {
  position: absolute; inset-inline: var(--sp-8) var(--sp-4); inset-block-end: 28%;
  border-block-end: 2px solid var(--line-strong); pointer-events: none;
}
.signature__x { position: absolute; inset-inline-start: var(--sp-3); inset-block-end: calc(28% - 2px); color: var(--muted);
  font-size: var(--fs-1); line-height: 1; pointer-events: none; }
.signature__actions { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-2); margin-block-start: var(--sp-2); }

/* ---- the calendar chart: homes down, nights across ---------------------------------------------------------------
   The chart scrolls inside its own container (both directions); the first column and the header row stick. A row
   is a flex line of fixed-width nights; a stay is one element whose width is its nights (one empty <i> per night),
   so no inline style is ever needed. */
.chart-wrap { position: relative; }
@media (max-width: 599.98px) { .chart-wrap { margin-inline: calc(-1 * var(--gutter)); } }
.chart-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); margin-block-end: var(--sp-3); }
.chart-toolbar__title { flex: 1 1 auto; font-weight: 700; font-size: var(--fs-1); min-inline-size: 8rem; }
.chart {
  --night-w: 44px;
  --head-w: 112px;
  --row-h: 52px;
  --head-h: 52px;
  position: relative;
  overflow: auto; overscroll-behavior: contain;
  max-block-size: max(320px, calc(var(--app-h) - var(--chart-reserve)));
  background: var(--surface);
  border-block: 1px solid var(--line);
  scroll-padding-inline-start: var(--head-w);
  scroll-padding-block-start: var(--head-h);
  scrollbar-width: thin;
}
.chart:focus-visible { outline-offset: -3px; }
@media (min-width: 600px) { .chart { --night-w: 52px; --head-w: 180px; border: 1px solid var(--line); border-radius: var(--r-sheet); } }
@media (min-width: 1200px) { .chart { --night-w: 56px; --head-w: 220px; } }
.chart__rows { inline-size: max-content; min-inline-size: 100%; }
.chart__row { display: flex; inline-size: max-content; min-inline-size: 100%; border-block-end: 1px solid var(--line); }
.chart__row:last-child { border-block-end: 0; }

/* header */
.chart__row--months, .chart__row--days { position: sticky; z-index: 3; background: var(--surface); }
.chart__row--months { inset-block-start: 0; block-size: 28px; border-block-end: 0; }
.chart__row--days { inset-block-start: 28px; block-size: var(--head-h); border-block-end: 1px solid var(--line-strong); }
.chart__corner {
  position: sticky; inset-inline-start: 0; z-index: 4; flex: none;
  inline-size: var(--head-w); background: var(--surface);
  border-inline-end: 1px solid var(--line-strong);
}
/* a month: its nights as empty spacers, its name stuck to the start while the month is in view */
.chart__month { flex: none; display: grid; overflow: clip; }
.chart__month > * { grid-area: 1 / 1; }
.chart__month-run { display: flex; }
.chart__month-run > i { flex: none; inline-size: var(--night-w); }
.chart__month-label {
  justify-self: start; align-self: end;
  position: sticky; inset-inline-start: var(--head-w);
  padding-inline: var(--sp-2); padding-block-end: 2px;
  font-size: var(--fs--1); font-weight: 700; white-space: nowrap;
}
.chart__month { position: relative; }
.chart__month + .chart__month::before {
  content: ""; position: absolute; inset-block: 0; inset-inline-start: 0; border-inline-start: 1px solid var(--line-strong);
}
.chart__day {
  flex: none; inline-size: var(--night-w);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0;
  border-inline-end: 1px solid var(--line);
  font-size: var(--fs--1); line-height: 1.2; color: var(--muted);
}
.chart__day .chart__dn {
  display: grid; place-items: center; min-inline-size: 28px; block-size: 24px; padding-inline: 2px;
  border-radius: var(--r-bar); font-size: var(--fs-0); font-weight: 700; color: var(--ink);
}
.chart__day.is-weekend { background: var(--sunk); }
.chart__day.is-today .chart__dn { background: var(--primary); color: var(--on-primary); }
.chart__day.is-today { color: var(--primary-ink); font-weight: 700; }
.chart__day.is-month-start, .chart__cell.is-month-start, .chart__bar.is-month-start { border-inline-start: 1px solid var(--line-strong); }

/* the home column: the whole cell is the home's link */
.chart__home {
  position: sticky; inset-inline-start: 0; z-index: 2; flex: none;
  inline-size: var(--head-w); min-block-size: var(--row-h);
  display: flex; background: var(--surface); border-inline-end: 1px solid var(--line-strong);
}
.chart__home-link {
  flex: 1; min-inline-size: 0; display: flex; flex-direction: column; justify-content: center; gap: 2px;
  min-block-size: var(--row-h); padding: 6px var(--sp-2) 6px var(--sp-3);
  color: var(--ink); text-decoration: none;
}
a.chart__home-link:hover .chart__home-name { text-decoration: underline; }
.chart__home-name {
  font-weight: 700; font-size: var(--fs--1); line-height: 1.25;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.chart__home-meta { font-size: 0.75rem; color: var(--muted); line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@media (min-width: 600px) { .chart__home-name { font-size: var(--fs-0); } .chart__home-meta { font-size: var(--fs--1); } }

/* nights */
.chart__cell, .chart__bar {
  position: relative; flex: none; display: flex; align-items: center;
  min-block-size: var(--row-h);
  border: 0; border-inline-end: 1px solid var(--line); margin: 0; padding: 0;
  background: transparent; font: inherit; color: var(--ink); text-decoration: none;
}
.chart__cell { inline-size: var(--night-w); justify-content: center; }
button.chart__cell { cursor: pointer; }
button.chart__cell:hover { background: var(--primary-tint); }
.chart__cell.is-weekend { background: var(--sunk); }
.chart__cell.is-today { background: var(--primary-tint); }
.chart__price { font-size: var(--fs--1); color: var(--muted); white-space: nowrap; }
.chart__cell.is-today .chart__price { color: var(--primary-ink); }
.chart__cell.is-closed { background: var(--closed); }
.chart__cell.is-closed::after { content: ""; inline-size: 12px; block-size: 2px; border-radius: 1px; background: var(--closed-ink); opacity: 0.7; }

/* a stay, a hold or a block: one element, as wide as its nights (one empty <i> per night in .chart__run). Its
   label sticks to the start edge while the stay is in view, so a long stay scrolled half out still says whose. */
.chart__bar { cursor: pointer; z-index: 1; display: grid; align-items: center; overflow: clip; }
.chart__bar > .chart__run, .chart__bar > .chart__label { grid-area: 1 / 1; }
.chart__run { display: flex; }
.chart__run > i { flex: none; inline-size: var(--night-w); block-size: 1px; }
.chart__bar::before {
  content: ""; position: absolute; inset: 7px 3px 7px 3px;
  background: var(--shape-bg); border: 2px solid var(--shape-edge); border-radius: var(--r-bar);
}
.chart__bar.is-blocked::before { border-width: 1px; }
.chart__bar.is-booked:hover::before { background: var(--booked-hover); }
.chart__bar.is-hold:hover::before { border-width: 3px; }
.chart__bar.is-cut-start::before { inset-inline-start: -1px; border-start-start-radius: 0; border-end-start-radius: 0; border-inline-start-width: 0; }
.chart__bar.is-cut-end::before { inset-inline-end: -1px; border-start-end-radius: 0; border-end-end-radius: 0; border-inline-end-width: 0; }
.chart__label {
  position: sticky; inset-inline-start: var(--head-w); z-index: 1;
  justify-self: start; max-inline-size: 100%; min-inline-size: 0;
  display: flex; align-items: center; gap: var(--sp-1);
  padding-inline: 12px 8px;
  color: var(--shape-ink); font-size: var(--fs--1); font-weight: 700; line-height: 1.2;
  white-space: nowrap;
}
.chart__label > span { overflow: hidden; text-overflow: ellipsis; }
.chart__bar.is-blocked .chart__label > span {
  background: var(--surface); color: var(--ink); padding: 1px 6px; border-radius: 2px; font-weight: 700;
}
.chart__label .icon { inline-size: 16px; block-size: 16px; flex: none; }
/* a stay with a problem: a red flag at its start */
.chart__bar.has-problem::after {
  content: ""; position: absolute; inset-block: 7px; inset-inline-start: 3px; inline-size: 6px;
  background: var(--problem); border-start-start-radius: var(--r-bar); border-end-start-radius: var(--r-bar);
}
.chart__bar.has-problem .chart__label { padding-inline-start: 18px; }
.chart__bar:focus-visible, .chart__cell:focus-visible { outline: 3px solid var(--focus); outline-offset: -3px; z-index: 3; }

/* the scroll affordance: a soft edge where more nights wait (kit.js sets the data attributes) */
.chart-wrap::before, .chart-wrap::after {
  content: ""; position: absolute; inset-block: 1px; z-index: 5; inline-size: 24px; pointer-events: none;
  opacity: 0; transition: opacity var(--t-fade) linear;
}
.chart-wrap::after { inset-inline-end: 0; background: linear-gradient(to left, var(--scrim), transparent); }
.chart-wrap::before { inset-inline-start: var(--head-w-out, 112px); background: linear-gradient(to right, var(--scrim), transparent); }
[dir="rtl"] .chart-wrap::after { background: linear-gradient(to right, var(--scrim), transparent); }
[dir="rtl"] .chart-wrap::before { background: linear-gradient(to left, var(--scrim), transparent); }
.chart-wrap[data-more-end]::after { opacity: 0.35; }
.chart-wrap[data-more-start]::before { opacity: 0.25; }
@media (min-width: 600px) {
  .chart-wrap::after { border-start-end-radius: var(--r-sheet); border-end-end-radius: var(--r-sheet); }
  .chart-wrap { --head-w-out: 180px; }
}
@media (min-width: 1200px) { .chart-wrap { --head-w-out: 220px; } }
.chart-hint { display: flex; align-items: center; gap: var(--sp-2); margin-block-start: var(--sp-2); font-size: var(--fs--1); color: var(--muted); }
@media (min-width: 1440px) { .chart-hint--phones { display: none; } }

/* ---- the month grid for one home --------------------------------------------------------------------------------- */
.month { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-sheet); overflow: hidden; }
.month__title { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); padding: var(--sp-2); border-block-end: 1px solid var(--line); }
.month__title h3 { font-size: var(--fs-1); padding-inline: var(--sp-2); }
.month__row { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); }
.month__row + .month__row { border-block-start: 1px solid var(--line); }
.month + .legend, .chart-wrap + .legend { margin-block-start: var(--sp-3); }
.month__wd { padding-block: var(--sp-2); text-align: center; font-size: var(--fs--1); color: var(--muted); }
.month__wd abbr { text-decoration: none; }
.month__day {
  position: relative; min-block-size: 64px; min-inline-size: 0;
  display: flex; flex-direction: column; align-items: stretch; justify-content: space-between;
  padding: var(--sp-1) 0 var(--sp-2);
  border: 0; border-inline-end: 1px solid var(--line); background: transparent;
  font: inherit; color: var(--ink); text-decoration: none; text-align: start;
}
.month__day:nth-child(7n) { border-inline-end: 0; }
button.month__day, a.month__day { cursor: pointer; }
button.month__day:hover { background: var(--primary-tint); }
.month__day.is-out { color: var(--muted); background: var(--sunk); }
.month__day.is-out > * { visibility: hidden; }
.month__dn { padding-inline: var(--sp-2); font-weight: 700; font-size: var(--fs--1); }
.month__day.is-today .month__dn { justify-self: start; align-self: flex-start; margin-inline-start: 4px; padding-inline: 4px;
  background: var(--primary); color: var(--on-primary); border-radius: var(--r-bar); }
.month__price { padding-inline: var(--sp-2); font-size: 0.75rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.month__day.is-closed { background: var(--closed); }
.month__day.is-closed .month__price { visibility: hidden; }
/* the band: the same bar as the chart, cut into days; caps at the stay's ends */
.month__band {
  display: flex; align-items: center; block-size: 22px; margin-block-start: var(--sp-1);
  background: var(--shape-bg); border: 2px solid var(--shape-edge); border-inline-width: 0;
  color: var(--shape-ink); font-size: 0.75rem; font-weight: 700; overflow: hidden; white-space: nowrap;
}
/* a band runs over the hairline into the next day, so a stay reads as one bar */
.month__day:not(.is-end):not(:nth-child(7n)) .month__band { position: relative; z-index: 1; margin-inline-end: -1px; }
.month__day.is-blocked .month__band { border-block-width: 1px; }
.month__day.is-start .month__band { margin-inline-start: 4px; border-inline-start-width: 2px; border-start-start-radius: var(--r-bar); border-end-start-radius: var(--r-bar); }
.month__day.is-end .month__band { margin-inline-end: 4px; border-inline-end-width: 2px; border-start-end-radius: var(--r-bar); border-end-end-radius: var(--r-bar); }
.month__day.is-blocked.is-start .month__band, .month__day.is-blocked.is-end .month__band { border-inline-width: 1px; }
.month__label { padding-inline: 4px; overflow: hidden; text-overflow: ellipsis; }
.month__day.is-blocked .month__label { background: var(--surface); color: var(--ink); margin-inline-start: 2px; border-radius: 2px; }

/* ---- the strip of nights: 14 nights, scrollable --------------------------------------------------------------- */
.strip {
  display: flex; gap: var(--sp-1); overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x proximity; scroll-padding-inline: var(--gutter);
  margin-inline: calc(-1 * var(--gutter)); padding: var(--sp-1) var(--gutter) var(--sp-3);
  list-style: none; scrollbar-width: thin;
}
.strip__night {
  position: relative; flex: none; scroll-snap-align: start;
  inline-size: 60px; min-block-size: 96px;
  display: flex; flex-direction: column; align-items: center; justify-content: space-between; gap: 2px;
  padding: var(--sp-2) var(--sp-1);
  border: 1px solid var(--line); border-radius: var(--r-control); background: var(--surface);
  font: inherit; color: var(--ink); text-decoration: none;
}
button.strip__night { cursor: pointer; }
button.strip__night:hover { border-color: var(--line-strong); }
.strip__wd { font-size: var(--fs--1); color: var(--muted); }
.strip__dn { font-size: var(--fs-1); font-weight: 700; line-height: 1.1; }
.strip__price { font-size: 0.75rem; color: var(--muted); white-space: nowrap; }
.strip__mark {
  display: block; inline-size: 100%; block-size: 10px;
  background: var(--shape-bg, transparent); border: 2px solid var(--shape-edge, transparent); border-radius: var(--r-bar);
}
.strip__night.is-free .strip__mark { border: 1px dashed var(--line-strong); }
.strip__night.is-blocked .strip__mark { border-width: 1px; }
.strip__night.is-today .strip__dn { color: var(--primary-ink); }
.strip__night.is-today { border-color: var(--primary); }
.strip__night[aria-pressed="true"], .strip__night.is-selected { background: var(--primary); border-color: var(--primary); color: var(--on-primary); }
.strip__night[aria-pressed="true"] .strip__wd, .strip__night[aria-pressed="true"] .strip__price { color: var(--on-primary); }
.strip__night.is-in-range { background: var(--primary-tint); border-color: var(--primary-tint); }
.strip__night:disabled { cursor: not-allowed; }
.strip__night:disabled .strip__dn { color: var(--muted); }

/* ---- sheet, dialog, toast --------------------------------------------------------------------------------------
   A sheet is a <dialog>: a bottom sheet on phones, a side panel from 900 px. kit.js opens it modally. */
.sheet, .dialog {
  border: 0; padding: 0; color: var(--ink); background: var(--surface);
  box-shadow: var(--sheet-shadow);
}
.sheet {
  margin: auto 0 0; inline-size: 100%; max-inline-size: 100%;
  max-block-size: calc(var(--app-h) - var(--safe-top) - 24px);
  border-radius: var(--r-sheet) var(--r-sheet) 0 0;
  display: flex; flex-direction: column;
}
.sheet:not([open]):not(.is-static) { display: none; }
.sheet::backdrop, .dialog::backdrop { background: var(--scrim); }
.sheet__grip { align-self: center; inline-size: 40px; block-size: 4px; border-radius: 2px; background: var(--line-strong); margin-block: var(--sp-2) 0; }
.sheet__head { display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-2) var(--sp-2) var(--sp-2) var(--sp-4); }
.sheet__head h2 { flex: 1; min-inline-size: 0; font-size: var(--fs-1); }
.sheet__body { flex: 1 1 auto; overflow-y: auto; overscroll-behavior: contain; padding: var(--sp-2) var(--sp-4) var(--sp-4); }
.sheet__foot {
  display: flex; flex-wrap: wrap; gap: var(--sp-2); justify-content: flex-end;
  padding: var(--sp-3) var(--sp-4) calc(var(--sp-3) + var(--safe-bottom));
  border-block-start: 1px solid var(--line);
}
.sheet__foot .btn { flex: 1 1 auto; }
@media (min-width: 600px) { .sheet__foot .btn { flex: 0 0 auto; } }
@media (min-width: 900px) {
  .sheet {
    margin: 0 0 0 auto; margin-inline: auto 0; block-size: var(--app-h); max-block-size: none;
    inline-size: min(480px, 100%); border-radius: var(--r-sheet) 0 0 var(--r-sheet);
  }
  [dir="rtl"] .sheet { border-radius: 0 var(--r-sheet) var(--r-sheet) 0; }
  .sheet__grip { display: none; }
  .sheet__head { padding-block-start: calc(var(--sp-3) + var(--safe-top)); }
}
/* a sheet drawn in place (the gallery shows one this way) */
.sheet.is-static { position: static; margin: 0; inline-size: 100%; max-block-size: none; block-size: auto; border-radius: var(--r-sheet); box-shadow: var(--sheet-shadow); }
.sheet.is-static .sheet__foot { padding-block-end: var(--sp-3); }
.sheet.is-static .sheet__head { padding-block-start: var(--sp-2); }

.dialog {
  inline-size: min(26rem, calc(100% - 2 * var(--gutter))); max-block-size: calc(var(--app-h) - 48px);
  border-radius: var(--r-sheet); padding: var(--sp-6);
}
.dialog:not([open]):not(.is-static) { display: none; }
.dialog h2 { font-size: var(--fs-1); margin-block-end: var(--sp-2); }
.dialog p { color: var(--muted); }
.dialog .actions { margin-block-start: var(--sp-6); justify-content: flex-end; }
.dialog .actions .btn { flex: 1 1 auto; }
.dialog.is-static { position: static; margin: 0; }

.toasts {
  position: fixed; z-index: 50; inset-inline: 0;
  inset-block-end: calc(var(--tabbar-h) + var(--safe-bottom) + var(--sp-3));
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-2);
  padding-inline: var(--gutter); pointer-events: none;
}
@media (min-width: 900px) { .toasts { inset-block-end: calc(var(--safe-bottom) + var(--sp-6)); } }
.toast {
  pointer-events: auto;
  display: flex; align-items: center; gap: var(--sp-3);
  max-inline-size: 32rem; min-block-size: var(--target); padding: var(--sp-2) var(--sp-2) var(--sp-2) var(--sp-4);
  background: var(--ink); color: var(--paper); border-radius: var(--r-control);
  transition: opacity var(--t-fade) linear;
}
.toast.is-leaving { opacity: 0; }
.toast__text { flex: 1; }
.toast .btn--quiet { color: var(--paper); }
.toast .btn--quiet:hover { background: transparent; text-decoration: underline; }
.toast.is-problem { border-inline-start: 6px solid var(--problem); }
.toast.is-static { position: static; }

@supports (transition-behavior: allow-discrete) {
  .sheet[open] { transition: transform var(--t-sheet) var(--ease), display var(--t-sheet) allow-discrete, overlay var(--t-sheet) allow-discrete; }
  @starting-style { .sheet[open] { transform: translateY(100%); } }
  @media (min-width: 900px) {
    @starting-style { .sheet[open] { transform: translateX(100%); } }
    @starting-style { [dir="rtl"] .sheet[open] { transform: translateX(-100%); } }
  }
  .toast { transition: opacity var(--t-fade) linear; }
  @starting-style { .toast { opacity: 0; } }
}

/* ---- the brand of the installing company ------------------------------------------------------------------------- */
.brand-mark { display: inline-flex; align-items: center; gap: var(--sp-2); font-weight: 700; }
.brand-mark img { block-size: 32px; inline-size: auto; max-inline-size: 160px; object-fit: contain; }

/* ---- the guest's pages: a simple top bar, one column ---------------------------------------------------------- */
.guest .main { padding-block-start: var(--sp-6); }
.guest .content { max-inline-size: 560px; }

/* ---- an error summary at the top of a form: a notice whose lines are links to the fields --------------------- */
.errors:focus { outline: 3px solid var(--focus); outline-offset: 2px; }
.errors__list { list-style: none; margin: var(--sp-1) 0 0; padding: 0; }
.errors__list a { display: inline-flex; align-items: center; min-block-size: var(--target); color: var(--problem-ink);
  font-weight: 700; }
/* a one-time code: large tabular figures in a short field, a big target */
.input--code { max-inline-size: 11ch; min-block-size: 56px; font-size: var(--fs-2); letter-spacing: 0.2em;
  font-variant-numeric: tabular-nums; }

/* ---- motion off, colours forced ------------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important; scroll-behavior: auto !important; }
  .btn__spinner { animation: none; border-inline-end-color: currentColor; border-block-end-color: transparent; }
}
@media (forced-colors: active) {
  .chart__bar::before, .shape, .row__bar, .month__band, .strip__mark, .stepper__bar { border: 2px solid CanvasText; }
  .is-booked.chart__bar::before, .shape.is-booked, .row__bar.is-booked { background: Highlight; }
  .tabbar__item[aria-current="page"]::before { background: Highlight; }
}
@media print {
  .tabbar, .topbar__actions, .composer, .toasts { display: none; }
  .chart { max-block-size: none; overflow: visible; }
}
