/* Self-hosted, not Fontshare's CDN. A webfont served by a third party is a
   third-party request on every page load, which is a doctrine rule 2 question
   (EU hosting, and the client's practitioners' IPs) rather than a styling one.
   Both files are variable (one request each, 38KB and 16KB). Fontshare's ITF
   Free Font Licence permits self-hosting and commercial use; re-read it before
   launch, as the website build notes also say.

   The ?v= is load-bearing: these filenames are not content-hashed and the
   files are served with a year's cache, so replacing one in place would
   otherwise leave every browser that has it on the old file. Bump v when a
   font file changes. (It already mattered once: the first Switzer self-hosted
   here was Fontshare's THIN static weight, taken from the top of their
   variable stylesheet, and every weight on the page was being synthesised
   from it.) */
@font-face{font-family:"General Sans";src:url("/fonts/general-sans-wght.woff2?v=1") format("woff2");
  font-weight:200 700;font-style:normal;font-display:swap}
@font-face{font-family:"Switzer";src:url("/fonts/switzer-wght.woff2?v=1") format("woff2");
  font-weight:100 900;font-style:normal;font-display:swap}

/* R-Space palette, carried from the website build's Site Styles
   (compass projects/rspace-relational-space/mockup/BUILD-NOTES.md).
   Yellow is a FILL ONLY — 1.5:1 on white, so it never carries text.
   Black on yellow is 12.4:1, which is why every yellow control is black-labelled.
   Radii sit a little tighter than the website's (8/12px there, same here for
   controls, 10px for panels): a dense admin table reads worse at 14px. */
:root{
  --paper:#f2f0e6; --card:#fff;
  --ink:#111; --ink-2:#4a4a45; --ink-3:#74726a;
  --line:#e3dfd2; --line-2:#cfc9b8;
  --yellow:#fccc00; --yellow-dk:#d9af00; --yellow-soft:#fcf0c0; --yellow-line:#e8d487;
  --yellow-ink:#6b5300;
  --sage:#bec4ad; --sage-soft:#e8ebe0; --sage-line:#bec4ad; --sage-ink:#3b4533;
  --terra:#cc9078;
  --stop:#9a4f33; --stop-soft:#f6e6df; --stop-line:#e2bca9;
  --wall:#111;
  --radius:8px; --radius-lg:10px; --radius-sm:5px;
  --head:"General Sans",ui-sans-serif,system-ui,"Segoe UI",Arial,sans-serif;
  --body:"Switzer",ui-sans-serif,system-ui,"Segoe UI",Arial,sans-serif;
  --shadow:0 1px 2px rgba(17,17,17,.04), 0 10px 26px -14px rgba(17,17,17,.16);
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{background:var(--paper);color:var(--ink);
  font:15px/1.5 var(--body);-webkit-font-smoothing:antialiased}
h1,h2,h3,.mark b,.btn,nav.main a,.eyebrow,.day .dn{font-family:var(--head)}
a{color:var(--ink);text-underline-offset:2px}
a:hover{color:var(--stop)}
.wrap{max-width:1180px;margin:0 auto;padding:0 16px}
/* The scripts hide the native controls they sit on, and the Go button, with
   the hidden attribute; a class's display must not undo it. */
[hidden]{display:none !important}
.vis-hidden{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ---------------- header ---------------- */
header{border-bottom:1px solid var(--line);background:var(--card)}
.bar{display:flex;align-items:center;gap:14px;min-height:60px;flex-wrap:wrap;padding-top:8px;padding-bottom:8px}
.mark{display:flex;align-items:baseline;gap:9px;font-weight:600;letter-spacing:-.015em;text-decoration:none;color:var(--ink)}
.mark .dot{width:10px;height:10px;background:var(--yellow);border:1.5px solid var(--ink);border-radius:50%;display:block;transform:translateY(-1px)}
.mark b{font-size:16px}
.org{color:var(--ink-3);font-size:13px;padding-left:14px;border-left:1px solid var(--line)}
.spacer{flex:1}
nav.main{display:flex;align-items:center;gap:4px;flex-wrap:wrap}
nav.main a{font-size:13.5px;text-decoration:none;color:var(--ink-2);padding:6px 10px;border-radius:var(--radius)}
nav.main a:hover{background:var(--yellow-soft);color:var(--ink)}
nav.main a[aria-current="page"]{background:var(--yellow-soft);color:var(--ink);font-weight:600;box-shadow:inset 0 -2px 0 var(--yellow)}
.whoami{font-size:13px;color:var(--ink-3);display:flex;align-items:center;gap:9px}
.whoami b{color:var(--ink);font-weight:550}
.badge{font-size:10px;letter-spacing:.06em;text-transform:uppercase;padding:2px 6px;border-radius:20px;font-weight:650;background:var(--yellow-soft);color:var(--yellow-ink)}
.count{display:inline-block;min-width:17px;padding:1px 5px;border-radius:20px;background:var(--stop);color:#fff;font-size:11px;font-weight:650;text-align:center;margin-left:4px}
/* The phone menu (views.js layout). Hidden above 620px, where everything in
   it is already on the bar. Below it, the signed-in bar is the brand and the
   Menu button; the panel drops over the page from the header's bottom edge. */
header{position:relative}
.phone-menu{display:none}
.phone-menu summary{list-style:none;display:flex;align-items:center;gap:8px;cursor:pointer;
  font-family:var(--head);font-size:14px;font-weight:600;color:var(--ink);
  padding:9px 13px;border:1px solid var(--line-2);border-radius:var(--radius);background:var(--card)}
.phone-menu summary::-webkit-details-marker{display:none}
.phone-menu summary .count{margin-left:0}
.phone-menu[open] summary{background:var(--yellow-soft);border-color:var(--yellow-line)}
.burger{position:relative;display:block;width:16px;height:2px;background:var(--ink);border-radius:1px;
  box-shadow:0 -5px 0 var(--ink),0 5px 0 var(--ink)}
.phone-menu-bd{position:absolute;z-index:30;left:0;right:0;top:100%;
  background:var(--card);border-bottom:1px solid var(--line);box-shadow:var(--shadow);padding:6px 16px 16px}
.phone-menu-bd .org{display:block;border-left:0;padding:8px 0 10px;border-bottom:1px solid var(--line)}
.phone-nav{display:flex;flex-direction:column;padding:8px 0;border-bottom:1px solid var(--line)}
.phone-nav a{display:flex;align-items:center;justify-content:space-between;min-height:44px;padding:0 12px;
  font-family:var(--head);font-size:15px;text-decoration:none;color:var(--ink-2);border-radius:var(--radius)}
.phone-nav a[aria-current="page"]{background:var(--yellow-soft);color:var(--ink);font-weight:600;box-shadow:inset 3px 0 0 var(--yellow)}
.phone-menu-bd .whoami{padding-top:14px}
.phone-menu-bd .whoami form{margin-left:auto}
@media (max-width:620px){
  .bar{min-height:0;gap:12px}
  .bar:has(.phone-menu) > .org,.bar > nav.main,.bar > .whoami{display:none}
  .phone-menu{display:block}
}
/* The Menu takes over wherever the bar stops fitting on one row, not only on a
   phone (Farias, 2026-10-30). Where that is depends on what is on the bar, so
   each kind gets its own width, measured with the name at its cap. The cap is
   what makes a fixed width hold for any name: 14ch shows the seeded names in
   full and trims longer ones, which the menu shows whole. Measured 2026-10-30:
   the admin bar needs 1,100px and a practitioner's 851px, plus the 32px
   gutter and a 15px scrollbar. Re-measure if a nav label or the brand changes.
   Re-measured 2026-11-09, when Room use made the admin nav seven links: at the
   old 10px padding the bar needed 1,186px, more than the 1,148px inside .wrap,
   so it wrapped at every width. The admin's links are tighter (7px, gap 2px)
   and the bar needs 1,132px; the Menu takes over below 1,180px. */
.bar > .whoami b{max-width:14ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bar-admin nav.main{gap:2px}
.bar-admin nav.main a{padding:6px 7px}
@media (max-width:1179px){
  .bar-admin > .org,.bar-admin > nav.main,.bar-admin > .whoami{display:none}
  .bar-admin .phone-menu{display:block}
}
@media (max-width:899px){
  .bar-member > .org,.bar-member > nav.main,.bar-member > .whoami{display:none}
  .bar-member .phone-menu{display:block}
}
/* Wider than a phone, the menu drops from its button as a panel on the right
   rather than as a sheet across the whole header. */
@media (min-width:621px){
  .phone-menu{position:relative}
  .phone-menu-bd{left:auto;right:0;top:calc(100% + 8px);width:320px;
    border:1px solid var(--line);border-radius:var(--radius-lg)}
}

/* ---------------- layout ---------------- */
/* Vertical padding only. These sit on the same element as .wrap, and a
   `padding: … 0 …` shorthand here wiped its 16px side gutter, which is why
   every page ran flush to the screen edge on a phone. */
.grid{display:grid;grid-template-columns:minmax(0,1fr) 330px;gap:26px;align-items:start;padding-top:26px;padding-bottom:56px}
@media (max-width:900px){.grid{grid-template-columns:minmax(0,1fr);gap:20px;padding-top:18px;padding-bottom:40px}}
.grid > .col{min-width:0}
.single{padding-top:26px;padding-bottom:56px;max-width:760px}
.panel{background:var(--card);border:1px solid var(--line);border-radius:var(--radius-lg);box-shadow:var(--shadow)}
.panel + .panel{margin-top:18px}
/* What follows a panel on the page (the buttons under a report, a back link)
   used to start on the panel's bottom edge. */
.panel + .acts-row,.panel + .lede{margin-top:18px}
.panel-hd{padding:14px 16px;border-bottom:1px solid var(--line);display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.panel-hd h2{margin:0;font-size:14px;font-weight:600;letter-spacing:-.01em}
.panel-hd .sub{font-size:12.5px;color:var(--ink-3)}
.panel-bd{padding:16px}
h1{font-size:22px;letter-spacing:-.02em;margin:0 0 4px}
.lede{color:var(--ink-2);font-size:14px;margin:0 0 18px}
/* The way back to the list a detail page came from, above its heading, so it
   is on the first screen however long the page is (F11, F28). */
.back{margin:0 0 8px;font-size:13px}
.back a{color:var(--ink-2)}

/* ---------------- date control ---------------- */
.datebar{display:flex;align-items:center;gap:14px;padding:12px 16px;border-bottom:1px solid var(--line);flex-wrap:wrap}
.datejump{position:relative;display:flex;align-items:center;gap:8px;flex:0 0 auto;flex-wrap:wrap}
.datejump label{font-size:10.5px;text-transform:uppercase;letter-spacing:.07em;color:var(--ink-3);white-space:nowrap}
.datejump input[type=date]{width:auto;padding:7px 9px;font-size:13px}
@media (max-width:620px){.datejump{width:100%}.datejump input[type=date],.datejump .dp{flex:1}}

/* ---------------- floor plans ---------------- */
/* Two floors since the basement went (F13). The SVG scales with its box and
   its text with it, so label sizes are set per rendered width (F40): the 2nd
   floor is drawn at about .42 of its viewBox on a desktop, and both floors at
   about .43 on a 375 px phone, so they get the large sizes; the 1st floor on a
   desktop (about .6) gets the base ones. Aim: captions 11 px or more on screen,
   room numbers about 19 px. */
.floors{display:grid;grid-template-columns:minmax(0,3fr) minmax(0,2fr);gap:22px;align-items:start}
.floor-lb{display:flex;align-items:baseline;gap:8px;margin:0 0 7px;font-size:11px;
  text-transform:uppercase;letter-spacing:.09em;color:var(--ink-3)}
.floor-lb i{font-style:normal;color:var(--line-2)}
svg.plan{display:block;width:100%;height:auto;overflow:visible}
@media (max-width:760px){.floors{grid-template-columns:minmax(0,1fr)}}
.plan .shell{fill:none;stroke:var(--wall);stroke-width:11}
.plan .win{stroke:#fff;stroke-width:7}
.plan .div{stroke:var(--wall);stroke-width:9;stroke-linecap:square}
.plan .fitting{fill:var(--wall)}
.plan .svc{fill:var(--sage-soft);stroke:var(--wall);stroke-width:4}
.plan .svc-t{fill:var(--ink-2);font-size:18px;letter-spacing:.08em}
.plan .circ{fill:#efecdf}
.plan .circ-t{fill:var(--ink-3);font-size:18px;letter-spacing:.08em}
.plan .stair{fill:none;stroke:var(--line-2);stroke-width:3}

/* Outlines are clipped to the room (plan.js), so a stroke of N shows N/2
   inside it and never sits on a wall. */
.room{cursor:pointer}
.room .hit{fill:#fff;stroke:var(--line-2);stroke-width:4;transition:fill .12s,stroke .12s}
.room text{text-anchor:middle;pointer-events:none}
.room .num{font-size:32px;font-weight:650;fill:var(--ink)}
.room .cap{font-size:18px;fill:var(--ink-3);letter-spacing:.07em}
.room .free{font-size:18px;fill:var(--ink-3)}
.floor-2 .plan .circ-t{font-size:26px}
.floor-2 .room .num{font-size:44px}
.floor-2 .room .cap{font-size:26px;transform:translateY(-8px)}
.floor-2 .room .free{font-size:26px;transform:translateY(10px)}
@media (max-width:760px){
  .plan .circ-t{font-size:26px}
  .plan .svc-t{font-size:20px}
  .room .num{font-size:44px}
  .room .cap{font-size:26px;transform:translateY(-8px)}
  .room .free{font-size:26px;transform:translateY(10px)}
}
.room[data-state="busy"] .hit{fill:var(--yellow-soft);stroke:var(--yellow-line)}
.room[data-state="busy"] .num{fill:var(--yellow-ink)}
.room[data-state="full"] .hit{fill:var(--stop-soft);stroke:var(--stop-line)}
.room[data-state="full"] .num{fill:var(--stop)}
/* Fill carries the room's STATE (white free, pale yellow partly booked,
   terracotta tint full), so hover and selection never touch it. Hover was the
   partly-booked fill until F14, and read as a state. Hover and keyboard focus
   draw a dark inner ring; the selected room ("you are here", F32) a thick
   yellow one, and its caption reads THIS ROOM. */
.room:hover .hit,.room:focus-visible .hit{stroke:var(--ink);stroke-width:8}
.room:hover .num,.room:focus-visible .num{text-decoration:underline;text-decoration-thickness:2px}
.room[data-sel="1"] .hit,.room[data-sel="1"]:hover .hit{stroke:var(--yellow);stroke-width:18}
.room[data-sel="1"] .cap{fill:var(--ink);font-weight:650}
.room:focus{outline:none}
.room.out{cursor:not-allowed}
.room.out .hit,.room.out:hover .hit{fill:url(#hatch);stroke:var(--line-2);stroke-width:2}
.room.out .num,.room.out .cap,.room.out .free{fill:var(--ink-3)}
.room.out:hover .num{text-decoration:none}

.legend{display:flex;flex-wrap:wrap;gap:14px;padding:12px 16px;border-top:1px solid var(--line);font-size:12.5px;color:var(--ink-2)}
.legend span{display:flex;align-items:center;gap:7px}
.sw{width:13px;height:13px;border-radius:3px;border:1.5px solid var(--line-2);display:block}
.sw.free{background:#fff}
.sw.busy{background:var(--yellow-soft);border-color:var(--yellow-line)}
.sw.full{background:var(--stop-soft);border-color:var(--stop-line)}
.sw.out{background:repeating-linear-gradient(45deg,#edeadf 0 3px,#e3dfd2 3px 6px)}

/* ---------------- forms & buttons ---------------- */
label.field{display:block;margin-bottom:13px}
label.field span{display:block;font-size:12.5px;color:var(--ink-2);margin-bottom:5px}
input[type=email],input[type=password],input[type=text],input[type=date],select,textarea{
  width:100%;font:inherit;font-size:14px;color:var(--ink);background:var(--card);
  border:1px solid var(--line-2);border-radius:var(--radius);padding:9px 10px}
input:focus,select:focus,textarea:focus{outline:2px solid var(--yellow-dk);outline-offset:-1px;border-color:var(--ink)}
.btn{font:inherit;font-size:14px;font-weight:600;padding:10px 15px;cursor:pointer;
  background:var(--yellow);color:var(--ink);border:1px solid var(--yellow-dk);border-radius:var(--radius);text-decoration:none;display:inline-block;text-align:center}
.btn:hover:not(:disabled){background:var(--yellow-dk)}
.btn:disabled{background:#efede4;color:var(--ink-3);border-color:var(--line);cursor:not-allowed}
.btn.block{width:100%}
.btn.ghost{background:var(--card);color:var(--ink-2);border-color:var(--line-2);font-weight:550}
.btn.ghost:hover{background:var(--paper);color:var(--ink)}
.btn.danger{background:var(--card);color:var(--stop);border-color:var(--stop-line);font-weight:550}
.btn.danger:hover{background:var(--stop-soft)}
.btn.sm{font-size:13px;padding:6px 11px}

/* ---------------- the application and practitioner forms ----------------
   `label.field span` above is a block, so a hint and an error are each their
   own line under the control without any extra structure. */
label.field .field-hint,label.field .field-err{margin:5px 0 0;font-size:12px;line-height:1.4}
label.field .field-hint{color:var(--ink-3)}
label.field .field-err{color:var(--stop);font-weight:600}
label.field.bad input,label.field.bad select,label.field.bad textarea{border-color:var(--stop-line);background:var(--stop-soft)}
.field .opt{font-style:normal;color:var(--ink-3);font-weight:400}
label.check{display:flex;gap:9px;align-items:flex-start;margin:0 0 13px;
  padding:10px 12px;border:1px solid var(--line-2);border-radius:var(--radius);background:var(--paper)}
label.check input{width:20px;height:20px;flex:0 0 auto;margin:0;accent-color:var(--ink)}
label.check span{display:block;font-size:13.5px;color:var(--ink-2)}
label.check.bad{border-color:var(--stop-line);background:var(--stop-soft)}
/* A hint or error that belongs to a checkbox sits after its label, not in it,
   so it needs the field styling `label.field` gives its own hints. */
label.check + .field-hint,label.check + .field-err{display:block;margin:-6px 0 13px;font-size:12px;line-height:1.4}
label.check + .field-hint{color:var(--ink-3)}
label.check + .field-err{color:var(--stop);font-weight:600}
/* A form that spans several panels: the panel carries the margin, not the form */
form > .panel{margin-bottom:16px}

/* auto-fit rather than a fixed 3: a thirteen-hour day in three columns is five
   rows with one slot stranded on the last. At ~88px the panel takes five
   columns on desktop and still falls back to three at 375px. */
.slots{display:grid;grid-template-columns:repeat(auto-fit,minmax(88px,1fr));gap:6px}
/* A slot is now a LINK to the confirm step, or a span when it is not takeable.
   Both carry two lines: the hour, and who holds it or that it is free — the
   holder's name used to live in a `title`, which a phone has no way to show. */
.slot{display:block;font:inherit;font-size:13px;padding:8px 5px;text-align:center;cursor:pointer;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--card);color:var(--ink);
  text-decoration:none}
.slot b{display:block;font-weight:600;font-size:13.5px}
.slot .who{display:block;font-size:11px;color:var(--ink-3);margin-top:2px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.slot:hover{border-color:var(--yellow-dk);background:var(--yellow-soft);color:var(--ink)}
.slot:hover .who{color:var(--ink-2)}
.slot.off{background:#f5f3ea;color:#6b6960;cursor:not-allowed}
.slot.off b{text-decoration:line-through}
.slot.off:hover{background:#f5f3ea;border-color:var(--line);color:#6b6960}
.slot.off .who{color:#6b6960}

/* ---------------- any room, one day ---------------- */
.single.wide{max-width:980px}
.gridscroll{overflow-x:auto}
.freegrid{width:100%;border-collapse:collapse;font-size:13px}
.freegrid th{font-family:var(--head);font-weight:600;text-align:left;color:var(--ink-2)}
.freegrid thead th{padding:0 4px 8px;border-bottom:1px solid var(--line);font-size:12px}
.freegrid thead th b{display:block;font-size:14px;color:var(--ink)}
.freegrid thead th span{display:block;font-weight:400;font-size:11px;color:var(--ink-3)}
.freegrid tbody th{white-space:nowrap;padding:3px 10px 3px 0;font-size:12.5px;font-weight:550}
.freegrid td{padding:3px 2px}
.cell{display:block;text-align:center;font-size:12px;padding:8px 4px;border-radius:var(--radius-sm);
  border:1px solid var(--line);text-decoration:none}
a.cell.free{background:var(--card);color:var(--ink-2)}
a.cell.free:hover{background:var(--yellow-soft);border-color:var(--yellow-dk);color:var(--ink)}
.cell.taken{background:var(--stop-soft);border-color:var(--stop-line);color:var(--stop)}
.cell.off{background:#f5f3ea;border-color:var(--line);color:#6b6960}
@media (max-width:620px){
  .freegrid{font-size:12px}
  .freegrid tbody th{padding-right:6px;font-size:11.5px}
  .cell{font-size:11px;padding:7px 2px}
}

/* ---------------- room use (views.js roomUsePage) ----------------
   Counts in a table. Each figure is a per cent over "N of M", so the share
   reads first and the hours stay in text. The empty-hours shading is four
   steps of the stop colour, darker for emptier, with black text on every
   step (10:1 or better), and the number is always written: the colour only
   helps the eye find the emptiest hours. */
.monthnav{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:0 0 16px;font-size:13px}
.usegrid{width:100%;border-collapse:collapse;font-size:13px}
.usegrid th{font-family:var(--head);font-weight:600;text-align:left;color:var(--ink-2)}
.usegrid thead th{padding:0 6px 8px;border-bottom:1px solid var(--line);font-size:12px;vertical-align:bottom}
.usegrid thead th b{display:block;font-size:14px;color:var(--ink)}
.usegrid th span{display:block;font-weight:400;font-size:11px;color:var(--ink-3)}
.usegrid th span.to{display:inline;font:inherit;color:inherit}
.usegrid tbody th,.usegrid tfoot th{white-space:nowrap;padding:6px 12px 6px 0;font-size:12.5px;font-weight:550}
.usegrid tbody th b,.usegrid tfoot th b{font-weight:600;color:var(--ink)}
.usegrid td{padding:6px;text-align:right;white-space:nowrap}
.usegrid tbody tr + tr > *{border-top:1px solid var(--line)}
.usegrid tfoot > tr > *{border-top:1.5px solid var(--line-2)}
.usegrid tr.now > *{background:var(--yellow-soft)}
.usegrid thead th.num,.usegrid thead th:not(:first-child){text-align:right}
.use b{display:block;font-family:var(--head);font-size:14px;font-weight:600;color:var(--ink)}
.use span{display:block;font-size:11.5px;color:var(--ink-3)}
.use.none{color:var(--ink-3)}
.usegrid.gaps td,.usegrid.gaps tfoot th{padding:2px}
.usegrid.gaps tbody tr + tr > *{border-top:0}
.usegrid.gaps thead th{text-align:center}
.usegrid.gaps tbody th,.usegrid.gaps tfoot th:first-child{padding:2px 10px 2px 0}
.gap{display:block;text-align:center;font-size:12px;padding:7px 4px;border-radius:var(--radius-sm);
  border:1px solid var(--line);color:var(--ink)}
.gap.g1{background:#fff}
.gap.g2{background:#f7ebe4;border-color:#ecd5c9}
.gap.g3{background:#efd2c4;border-color:#e2bca9}
.gap.g4{background:#e2b5a0;border-color:#d39e86}
.gap.none{background:#f5f3ea;color:#6b6960}
.sw.gap{padding:0}
@media (max-width:620px){
  .usegrid{font-size:12px}
  .usegrid td{padding:6px 4px}
  .use b{font-size:13px}
  .gap{font-size:11px;padding:6px 1px}
  .usegrid th span.to,.usegrid thead th span.floor{display:none}
}

/* ---------------- the confirm step ---------------- */
.amount{display:block;padding:13px 15px;border:1px solid var(--yellow-line);
  background:var(--yellow-soft);border-radius:var(--radius);margin:0 0 13px}
.amount-k{display:block;font-size:11px;text-transform:uppercase;letter-spacing:.07em;color:var(--yellow-ink)}
.amount-v{display:block;font-family:var(--head);font-size:30px;font-weight:650;color:var(--ink);line-height:1.2}
.amount-n{display:block;font-size:12.5px;color:var(--yellow-ink);margin-top:4px;line-height:1.55}
.muted{color:var(--ink-3);font-weight:400}

/* ---------------- the date picker (public/daypicker.js) and the select (public/select.js) ----------------
   Every rule here styles an element those files create. Nothing the server
   renders depends on them, so with scripting off this block matches nothing.
   Touch: every control a finger has to hit is at least 44px tall. The
   `label.field span` rule above would reach inside, so nothing here is a span. */
.datebar-link{margin-left:auto;font-size:12.5px;color:var(--ink-2);white-space:nowrap}
.dp,.cs{position:relative}
.dp-field,.cs-field{display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;min-height:44px;
  font:inherit;font-size:14px;color:var(--ink);text-align:left;cursor:pointer;
  background:var(--card);border:1px solid var(--line-2);border-radius:var(--radius);padding:9px 10px}
.dp-field:hover,.cs-field:hover{border-color:var(--ink-3)}
.dp-field:focus,.cs-field:focus{outline:2px solid var(--yellow-dk);outline-offset:-1px;border-color:var(--ink)}
.dp-val,.cs-val{font-weight:450}
.dp-field.dp-empty .dp-val{color:var(--ink-3)}
/* A calendar and a chevron, drawn in CSS so neither is a file or a font. */
.dp-ico{flex:0 0 auto;width:15px;height:14px;border:1.5px solid var(--ink-2);border-top-width:4px;border-radius:3px}
.cs-ico{flex:0 0 auto;width:8px;height:8px;border-right:1.5px solid var(--ink-2);border-bottom:1.5px solid var(--ink-2);
  transform:translateY(-2px) rotate(45deg);margin-right:4px}
.cs-field[aria-expanded=true] .cs-ico{transform:translateY(2px) rotate(225deg)}
label.field.bad .dp-field,label.field.bad .cs-field,.dp.bad .dp-field{border-color:var(--stop-line);background:var(--stop-soft)}
.dp-err{margin:5px 0 0;font-size:12px;line-height:1.4;color:var(--stop);font-weight:600}
/* On the booking bar the field sits on one line with its label. */
.datejump .dp-field{width:auto;min-width:190px;font-size:13.5px}
@media (max-width:620px){.datejump .dp-field{width:100%}}

/* Directly below its field, like a dropdown (F9). daypicker.js pulls it left
   if a phone's edge would cut it off. */
.dp-panel,.cs-list{position:absolute;z-index:20;top:100%;left:0;margin-top:6px;
  background:var(--card);border:1px solid var(--line-2);border-radius:var(--radius-lg);box-shadow:var(--shadow)}
.dp-panel{padding:10px;width:min(340px,calc(100vw - 32px))}
.dp-hd{display:flex;align-items:center;gap:4px;margin-bottom:6px}
.dp-title{flex:1;text-align:center;font-family:var(--head);font-size:14.5px}
.dp-nav{flex:0 0 auto;width:44px;height:44px;font:inherit;font-size:20px;line-height:1;cursor:pointer;
  color:var(--ink);background:var(--card);border:1px solid var(--line);border-radius:var(--radius)}
.dp-nav:hover:not(:disabled){background:var(--paper);border-color:var(--line-2)}
.dp-nav:disabled{color:var(--line-2);cursor:not-allowed}
.dp-nav:focus-visible,.dp-day:focus-visible{outline:2px solid var(--ink);outline-offset:1px}
.dp-grid{width:100%;border-collapse:separate;border-spacing:2px;table-layout:fixed}
.dp-grid th{font-size:10.5px;font-weight:500;text-transform:uppercase;letter-spacing:.05em;color:var(--ink-3);
  text-align:center;padding:2px 0 4px}
.dp-grid td{height:44px;padding:0;text-align:center;font-size:13.5px;border-radius:var(--radius-sm)}
.dp-day{cursor:pointer;border:1px solid var(--line);background:var(--card);color:var(--ink)}
.dp-day:hover:not([aria-disabled=true]){border-color:var(--yellow-dk)}
.dp-day.today{font-weight:650;text-decoration:underline;text-underline-offset:3px}
.dp-day.busy{background:var(--yellow-soft);border-color:var(--yellow-line);color:var(--yellow-ink)}
.dp-day.full{background:var(--stop-soft);border-color:var(--stop-line);color:var(--stop);
  cursor:not-allowed;text-decoration:line-through}
.dp-day.out{color:var(--line-2);border-color:transparent;background:transparent;cursor:default}
.dp-day.sel{background:var(--ink);border-color:var(--ink);color:#fff;font-weight:650}
.dp-legend{display:flex;flex-wrap:wrap;gap:10px;margin-top:8px;font-size:11.5px;color:var(--ink-2)}
.dp-legend div{display:flex;align-items:center;gap:5px}
.dp-note{margin:8px 0 0;font-size:11.5px;color:var(--ink-3);line-height:1.5}
.dp-ft{margin-top:8px;display:flex;justify-content:flex-end}
.dp-ft .btn{min-height:44px}

.cs-list{right:0;max-height:min(320px,60vh);overflow-y:auto;padding:4px}
.cs-opt{display:flex;align-items:center;min-height:44px;padding:8px 10px;border-radius:var(--radius-sm);
  font-size:14px;cursor:pointer;line-height:1.35}
.cs-opt.active{background:var(--paper);outline:1.5px solid var(--ink-3);outline-offset:-1.5px}
.cs-opt[aria-selected=true]{font-weight:650}
.cs-opt[aria-selected=true]::after{content:"";margin-left:auto;flex:0 0 auto;width:5px;height:10px;
  border-right:2px solid var(--ink);border-bottom:2px solid var(--ink);transform:rotate(45deg) translate(-2px,-2px)}
.cs-opt[aria-disabled=true]{color:var(--ink-3);cursor:not-allowed}

/* ---------------- notes ---------------- */
.note{font-size:13px;line-height:1.55;padding:11px 13px;border-radius:var(--radius);margin:0 0 13px}
.note.ok{background:var(--sage-soft);color:var(--sage-ink);border:1px solid var(--sage-line)}
.note.warn{background:var(--yellow-soft);color:var(--yellow-ink);border:1px solid var(--yellow-line)}
.note.stop{background:var(--stop-soft);color:var(--stop);border:1px solid var(--stop-line)}
.note.plain{background:var(--paper);color:var(--ink-2);border:1px solid var(--line)}
.note b{font-weight:650}
.note:last-child{margin-bottom:0}
/* A note below a control or a block of them gets the same gap as a note below
   a note. These were each patched with an inline margin, or not at all. */
.btn + .note,form + .note,.acts-row + .note,.slots + .note,.gridscroll + .note{margin-top:13px}
/* A note placed straight in a panel, outside .panel-bd (a flash, a report's
   refusal line), carries the panel's padding itself instead of touching its
   edges. */
.panel > .note{margin:14px 16px}
.panel > .note:last-child{margin-bottom:16px}

/* ---------------- lists & tables ---------------- */
.rows{margin:0;padding:0;list-style:none}
.rows li{display:flex;align-items:center;gap:12px;padding:12px 16px;border-bottom:1px solid var(--line)}
.rows li:last-child{border-bottom:0}
.rows .grow{flex:1;min-width:0}
.rows .grow b{display:block;font-weight:550}
.rows .grow span{font-size:12.5px;color:var(--ink-3)}
/* Each extra line in a row is its own line on every list, not only on request
   rows: a cancelled booking's reason used to run on from its date. */
.rows .grow .what,.rows .grow .meta,.rows .grow .why{display:block;margin-top:3px}
.rows .grow .why.block{color:var(--stop)}
/* A value beside a row's text (a rate) shares the row rather than taking it:
   "no rate set · would charge €20.00/hr" squeezed the name to 34px. */
.rows:not(.kv) li > .v{flex:0 1 auto;max-width:55%;text-align:right}
.rows .acts{display:flex;gap:6px;flex-shrink:0}
.pill{font-size:10.5px;letter-spacing:.05em;text-transform:uppercase;padding:3px 7px;border-radius:20px;font-weight:650;white-space:nowrap}
.pill.ok,.pill.approved{background:var(--sage-soft);color:var(--sage-ink)}
.pill.soon,.pill.pending{background:var(--yellow-soft);color:var(--yellow-ink)}
.pill.no,.pill.rejected{background:var(--stop-soft);color:var(--stop)}
.pill.cancelled{background:#edeadf;color:var(--ink-3)}
.empty{padding:26px 16px;text-align:center;color:var(--ink-3);font-size:13.5px}

/* A request row carries four facts and three controls, so it gets room to
   breathe and an explicit reading order rather than one dense line. */
.panel-lede{margin:0;padding:12px 16px;border-bottom:1px solid var(--line);font-size:13px;color:var(--ink-2);line-height:1.55}
.rows li.req{align-items:flex-start;padding:15px 16px;gap:14px}
.rows li.req .grow b{font-size:14.5px}
.rows li.req .what{display:block;font-size:13.5px;color:var(--ink);margin-top:4px}
.rows li.req .meta{display:block;font-size:12.5px;color:var(--ink-3);margin-top:4px}
.rows li.req .why{display:block;font-size:12.5px;margin-top:6px}
.rows li.req .why.block{color:var(--stop)}
.rows li.req .why.warn{color:var(--yellow-ink)}
/* The buttons take a row of their own under the text, with the gate pill
   staying top right: one row of pill and three buttons read as one control. */
.rows li.req{flex-wrap:wrap;row-gap:10px}
.rows li.req .acts{flex-wrap:wrap;flex:1 0 100%;justify-content:flex-start}
.rows li.req:has(.pick) .acts{padding-left:34px}
.rows li.req .acts:not(:has(*)){display:none}
/* Any list row on a phone: the actions drop under the text rather than
   squeezing it into a column one word wide. */
@media (max-width:620px){
  .rows li:has(.acts *){flex-wrap:wrap;row-gap:10px;align-items:flex-start}
  .rows li .acts:has(*){flex:1 0 100%;flex-wrap:wrap}
  .rows li .acts:not(:has(*)){display:none}
}

/* selecting several requests. The checkbox is the whole of the selection UI:
   no script runs on this page, so "tick the ones that pass" is a link that
   re-renders the queue pre-ticked (?select=passing), not a toggle. */
/* The label is the tap target, padded out to 32px around a 20px box. */
.rows li.req .pick{flex:0 0 auto;display:flex;align-items:center;padding:6px;margin:-6px;cursor:pointer}
.rows li.req .pick input{width:20px;height:20px;margin:0;accent-color:var(--ink);cursor:pointer}
.batch-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:13px 16px;border-top:1px solid var(--line);background:var(--paper)}
.batch-bar .batch-pick{display:flex;gap:6px;flex-wrap:wrap;flex:1}
.batch-bar .batch-go{display:flex;gap:6px;flex-wrap:wrap}
.batch-reason{display:block;padding:0 16px 14px;font-size:12.5px;color:var(--ink-3);background:var(--paper)}
.batch-reason span{display:block;margin-bottom:5px}
.batch-reason input{width:100%;box-sizing:border-box}
@media (max-width:620px){.batch-bar .batch-go{width:100%}}
/* Where a "Tick all" link's #fragment lands after the reload (F31): a little
   air above it rather than flush with the top of the screen. */
#queue,#release{scroll-margin-top:12px}
/* On the queue the bar and its reason come before the rows (F44). */
.batch-top{border-bottom:1px solid var(--line)}
/* With nothing to offer (one releasable room, so no "tick all") the bar was
   an empty grey band. */
.batch-bar:not(:has(a,button)){display:none}
/* A list that follows a form's own panel-bd in the same panel needs the rule
   the panel header would otherwise give it. */
.panel > form + .rows{border-top:1px solid var(--line)}

/* key/value list on one request */
/* On the confirm screens the details follow the button (F44), so they need
   the rule the panel header used to give them. */
.panel > .panel-bd + .rows.kv,.panel > .rows.kv + .rows{border-top:1px solid var(--line)}
.rows.kv li{align-items:flex-start;gap:16px}
.rows.kv .k{flex:0 0 140px;font-size:11px;text-transform:uppercase;letter-spacing:.07em;color:var(--ink-3);padding-top:2px}
.rows.kv .v{flex:1;min-width:0;font-size:14px}
@media (max-width:620px){.rows.kv li{flex-direction:column;gap:3px}.rows.kv .k{flex:none}}
/* The gateway's own field names on Check with gateway (PR #78): kept in their
   case, so they can be quoted exactly, and wrapped where they are long. The
   wider column is for wide screens only: stacked on a phone, a flex-basis
   would set the label's height instead. */
.rows.kv.fields .k{text-transform:none;letter-spacing:0}
.rows.kv.fields .k code{font-size:12px;overflow-wrap:anywhere}
@media (min-width:621px){.rows.kv.fields .k{flex-basis:230px}}
.acts-row{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.acts-row form{display:inline}

/* "or make it every Tuesday" — the way into a weekly booking, on the confirm
   screen. A plain GET form, so it works with scripting off; separated from the
   single-hour button by a rule rather than a second panel, because it is the
   same request with one more question asked of it. */
.repeat{margin-top:18px;padding-top:16px;border-top:1px solid var(--line)}
.repeat h3{font-family:var(--head);font-size:15px;font-weight:650;margin:0 0 5px}
.repeat p{font-size:13px;color:var(--ink-2);line-height:1.6;margin:0 0 12px}
.repeat label{display:block;font-size:11px;text-transform:uppercase;letter-spacing:.07em;color:var(--ink-3);margin-bottom:5px}
.repeat input[type=date]{display:block;font:inherit;font-size:14px;padding:8px 10px;border:1px solid var(--line);border-radius:7px;background:#fff;color:var(--ink);margin:0 0 10px}
.repeat .muted{display:block;font-size:12px;margin-top:9px;line-height:1.55}

/* ---------------- footer ---------------- */
/* --ink-3 is 4.83:1 on white but only 4.22:1 on the cream ground, so the
   footer carries its own slightly darker grey (4.8:1 on cream). */
/* footer.wrap, not footer: .wrap's own padding outranks a type selector, so
   this vertical padding never applied. */
footer.wrap{border-top:1px solid var(--line);margin-top:8px;padding-top:28px;padding-bottom:40px;font-size:12px;color:#6b6960;line-height:1.7}
footer .powered{color:var(--ink-2)}
footer .powered b{font-weight:600;color:var(--ink)}

/* ---------------- a payment link on Payments (docs/decisions.md §18b)
   A read-only field under the session, with the Copy button public/copy.js
   adds beside it. With scripting off it is the field alone. */
.rows .grow .paylink{display:block;margin-top:8px}
.rows .grow .paylink label{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.rows .grow .paylink label > span{font-size:12px;color:var(--ink-3);flex:0 0 auto}
.rows .grow .paylink input{flex:1 1 220px;min-width:0;width:auto;font-size:12.5px;padding:6px 9px;background:var(--paper);color:var(--ink-2)}
.rows .grow .paylink .copy-btn{flex:0 0 auto;min-height:32px}

/* ---------------- passwords (docs/decisions.md §27)
   The signed-in name is the link to Your account; it looks as it did, and
   says it is a link on hover and focus. The link an administrator copies
   takes the payment link's field, outside a list. */
.whoami a.who{color:inherit;text-decoration:none;border-radius:var(--radius)}
.whoami a.who:hover b,.whoami a.who:focus-visible b,.whoami a.who[aria-current="page"] b{text-decoration:underline;text-underline-offset:3px}
.paylink.resetlink{margin:14px 0}
.paylink.resetlink label{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.paylink.resetlink label > span{font-size:12px;color:var(--ink-3);flex:0 0 auto}
.paylink.resetlink input{flex:1 1 260px;min-width:0;width:auto;font-size:13px;padding:7px 10px;background:var(--paper);color:var(--ink)}
.paylink.resetlink .copy-btn{flex:0 0 auto;min-height:34px}
.rows .grow .row-form{margin:10px 0 18px}

/* ---------------- the public Data Processing Addendum (dpa.js) ---------------- */
/* Running legal text: a reading measure, not the dense admin type. Tables
   scroll inside their own box on a phone, never the page. */
.legal{line-height:1.6;font-size:14.5px}
.legal h2{font-size:18px;letter-spacing:-.015em;margin:34px 0 10px;padding-top:6px;border-top:1px solid var(--line)}
.legal h3{font-size:15px;margin:22px 0 6px}
.legal h4{font-size:14px;margin:18px 0 6px;color:var(--ink-2)}
.legal p,.legal ul,.legal ol{margin:0 0 12px}
.legal ul,.legal ol{padding-left:22px}
.legal li{margin:4px 0}
.legal a{overflow-wrap:anywhere}
.legal .version{font-size:13.5px;color:var(--ink-2);margin:-8px 0 18px}
.legal .toc{margin:10px 0 0;padding-left:18px;columns:2;column-gap:28px}
@media (max-width:600px){.legal .toc{columns:1}}
.legal .panel{margin:12px 0 16px}
.legal .panel-bd > :last-child{margin-bottom:0}
.tbl-wrap{overflow-x:auto;margin:0 0 14px;border:1px solid var(--line);border-radius:var(--radius-lg);background:var(--card)}
.legal-tbl{width:100%;border-collapse:collapse;font-size:13.5px}
.legal-tbl th,.legal-tbl td{text-align:left;vertical-align:top;padding:9px 12px;border-bottom:1px solid var(--line)}
.legal-tbl tr:last-child > *{border-bottom:0}
.legal-tbl thead th{font-weight:600;background:var(--yellow-soft)}
.legal-tbl tbody th{font-weight:600;width:34%}
@media (max-width:600px){.legal-tbl tbody th{width:40%}}
.subproc{display:grid;grid-template-columns:minmax(0,11em) minmax(0,1fr);gap:8px 16px;margin:0;font-size:13.5px}
.subproc dt{font-weight:600}
.subproc dd{margin:0}
@media (max-width:600px){.subproc{grid-template-columns:minmax(0,1fr);gap:2px}.subproc dd{margin-bottom:10px}}
/* Only on a local preview (ANTEROOM_DPA_PREVIEW=1): an unanswered value. */
mark.pending{background:var(--stop-soft,#f7dcd6);color:var(--stop,#9b2c1a);padding:0 4px;border-radius:4px;font-weight:600}
footer a{color:inherit}

/* The guide (guide.js): a heading, a paragraph and one screenshot per step.
   Wider than .single so a screenshot reads near its own size; each one links
   to itself at full size. */
.guide.single{max-width:900px}
.guide h2{font-size:18px;margin:34px 0 4px;padding-top:14px;border-top:1px solid var(--line)}
.guide-nav{font-size:13px;color:var(--ink-3);margin:-8px 0 14px}
.guide-nav [aria-current]{color:var(--ink);font-weight:600}
.guide-toc{font-size:13.5px;color:var(--ink-2);margin:0 0 8px;padding-left:22px;columns:2 220px;column-gap:28px}
.guide-toc a{color:inherit}
.guide-step{margin:22px 0 0;scroll-margin-top:16px}
.guide-step h3{font-size:16px;margin:0 0 4px}
.guide-step h3 a{color:inherit;text-decoration:none}
.guide-step h3 a:hover{text-decoration:underline}
.guide-n{display:inline-block;min-width:24px;height:24px;line-height:24px;margin-right:8px;border-radius:999px;background:var(--yellow);color:var(--ink);font-size:12.5px;text-align:center}
.guide-step p{margin:0 0 10px;max-width:68ch}
.guide-shot{margin:0}
.guide-shot a{display:block}
.guide-shot img{display:block;max-width:100%;height:auto;border:1px solid var(--line-2);border-radius:var(--radius);background:var(--card);box-shadow:var(--shadow)}
.guide-pages{list-style:none;margin:6px 0 18px;padding:0;display:grid;gap:10px}
.guide-pages a{display:block;padding:14px 16px;background:var(--card);border:1px solid var(--line);border-radius:var(--radius-lg);color:var(--ink);text-decoration:none;box-shadow:var(--shadow)}
.guide-pages a:hover{border-color:var(--line-2)}
.guide-pages b{display:block;font-family:var(--head);font-size:16px}
.guide-pages span{font-size:13.5px;color:var(--ink-2)}
.guide-line{margin:22px 0 0;max-width:68ch;padding:10px 14px;border-left:3px solid var(--yellow);background:var(--card);border-radius:0 var(--radius) var(--radius) 0}

/* The monthly payments download on Payments (views.js paymentsPage): the
   month and its button on one line, the button dropping under on a phone. */
form.download{display:flex;align-items:flex-end;gap:10px;flex-wrap:wrap}
form.download label.field{margin:0;flex:1 1 180px}

/* ---------------- receipts (views.js receiptPage, docs/decisions.md §27)
   One panel that reads as a document on screen, and prints alone: the
   header, the footer, the way back and the Print row stay off the paper. */
.receipt-hd{display:flex;align-items:baseline;justify-content:space-between;gap:16px;flex-wrap:wrap;padding:20px 16px 14px;border-bottom:1px solid var(--line)}
.receipt-hd h1{margin:0}
.receipt-from{margin:0;text-align:right;font-size:14px}
.receipt .sub-line,.receipt-from .sub-line{display:block;font-size:12.5px;color:var(--ink-3);margin-top:2px}
.receipt .rows.kv .v code{font-size:13px}
.receipt-foot{margin:12px 0 0;font-size:12px;color:var(--ink-3)}
.print-row{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.print-row .note-inline{font-size:12.5px;color:var(--ink-3)}
@media print{
  header,footer,.no-print{display:none !important}
  body{background:#fff}
  .receipt-page{max-width:none;padding:0}
  .receipt{box-shadow:none;border:1px solid #999}
  .receipt .note.plain{background:#fff;border-color:#bbb}
}
