/* ---- UI kit 2.20.0 (CSS) -------------------------------------------------------------------------------------------------------------------------------------
   The master is kit/kit.css in the projects' root folder. Every page of every app carries an EXACT copy of it, from this first line to its end line, and a test fails if it
   differs: change it only in the master, then copy it everywhere. It is written only in tokens: the app's brand file sets them (kit/README.md lists them, and
   brand-template.css holds the first brand's values to start from). The sizes (--gap, --kit-pad, --kit-radius, --kit-field-h, --kit-head-line, --kit-card-closed) are
   the kit's own, below. The markup it expects: header > div.brand (icon, h1 name) + div.actions (div.extras: the page buttons, each with its kit class, which kit.js puts in the one order (kit 2.16.0, README);
   div.controls: button#refresh with its icon, then button#logout, empty: the kit draws its icon). */
html { -webkit-text-size-adjust:100%; text-size-adjust:100%; background:var(--bg); }          /* no bigger text when a phone is turned; a pull past the bottom of the page shows the page's own colour (kit 1.3.4: it showed a red strip) */
html { scrollbar-gutter:stable; }          /* the scrollbar's place is always kept, so the page does not shake sideways when a section opens or closes and the scrollbar comes or goes (kit 2.5.2; a short page on a classic scrollbar shows a strip in the page colour there, accepted) */
* { box-sizing:border-box; }
body { margin:0; font-family:var(--font, -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif); background:var(--bg); color:var(--ink); min-height:100vh; min-height:100dvh; }
html, body { max-width:100%; overflow-x:clip; }          /* nothing wider than the screen can widen the page (iOS would zoom the whole page out and keep it so after turning the phone) */
/* (kit 2.11.0) One page width: the whole page, a side menu included, is <main>, which no app's stylesheet widens or narrows; the render test measures it. */
main { width:100%; max-width:640px; margin:0 auto; padding:16px max(16px, env(safe-area-inset-right)) calc(16px + env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left)); }
@media (min-width:760px) { main { max-width:1320px; } }
header { position:sticky; top:0; z-index:100; background:var(--kit-header); color:var(--kit-on-header); border-bottom:4px solid var(--kit-line);
         display:flex; justify-content:space-between; align-items:center; gap:10px 12px;
         padding:calc(12px + env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) 12px max(16px, env(safe-area-inset-left)); }          /* opaque, and clear of the clock and the notch */
header::before { content:""; position:absolute; left:0; right:0; bottom:100%; height:100vh; pointer-events:none; background:var(--kit-header); }          /* behind the clock, and in a pull past the top, is the header's colour (it moves with the header), never a grey band */
header .brand { display:flex; align-items:center; gap:10px; flex:1 1 auto; min-width:0; }
header .brand img { border-radius:7px; flex:none; }
header h1 { font-size:1.15rem; font-weight:700; margin:0; line-height:1.2; overflow-wrap:break-word; min-width:0; }          /* the name is never cut short: a long one wraps between its words (kit 2.2.1: it split inside one); a word wider than the room it has is the only thing ever broken */
header .actions { display:flex; align-items:center; gap:10px; flex:none; }
header .extras, header .controls { display:flex; align-items:center; gap:10px; flex:none; } header .extras { flex-wrap:wrap; justify-content:flex-end; }
/* every control in the header is one size (44px, easy to hit) and one look, whether it is text, a link to another page or an icon */
header button, header a.hbtn { box-sizing:border-box; height:44px; min-width:44px; display:inline-flex; align-items:center; justify-content:center; padding:0 12px; line-height:1;
                               background:transparent; border:1px solid var(--kit-on-header); color:var(--kit-on-header); border-radius:6px; font:inherit; font-size:.85rem;
                               text-decoration:none; white-space:nowrap; flex:none; cursor:pointer; position:relative; }
header button[aria-pressed="true"] { background:var(--kit-on-header); color:var(--kit-header); font-weight:700; }          /* a switch that is on */
header #refresh svg, header .kit-admin-view svg, header #logout svg { width:18px; height:18px; fill:none; stroke:currentColor; stroke-width:2.4; stroke-linecap:round; stroke-linejoin:round; }
header #refresh { touch-action:manipulation; }                                                                                  /* two quick taps are a full refresh, never a zoom */
header #refresh.kit-refreshing svg { animation:kit-spin .8s linear infinite; }                                                  /* one tap, shown at once */
header #refresh.kit-refreshing-all { background:var(--kit-on-header); color:var(--kit-header); }                                /* two taps: a full refresh */
@media (prefers-reduced-motion: reduce) { header #refresh.kit-refreshing svg { animation-duration:3s; } }
/* a small screen: the name and, beside it, Refresh and Log Out on the first line; beneath, on a line of their own (if there is anything on it), the page buttons, justified to the right */
@media (max-width:640px) {
  header { flex-wrap:wrap; } header .actions { display:contents; } header .brand { order:1; flex:1 1 9rem; } header .controls { order:2; } header .extras { order:3; flex:1 0 100%; flex-wrap:wrap; justify-content:flex-end; }
  /* (kit 2.2.1) a name whose longest word will not fit beside Refresh and Log Out: the script marks the header kit-tools-down, the name has the first line to itself and
     the tools go down to the second, at its right beside the page buttons (or under them when the line is full), so the name is never split inside a word or under the cog */
  header.kit-tools-down .brand { flex-basis:100%; } header.kit-tools-down .extras { flex:1 1 auto; } header.kit-tools-down .controls { order:4; margin-left:auto; }
}
@media (min-width:641px) { header { flex-wrap:wrap; } header .brand { flex:1 1 9rem; min-width:min(9rem, 100%); } header .actions { margin-left:auto; } }          /* a tablet: the name keeps room for its words (kit 1.4.0: it broke inside one at 768px), and the buttons go under it, to the right, when they do not fit beside it */
@media (max-height:500px) { header { padding-top:calc(6px + env(safe-area-inset-top)); padding-bottom:6px; } }          /* a phone on its side: a shorter header leaves room for the page */
@media (pointer:coarse) { input, select, textarea { font-size:16px !important; } }          /* (a box under 16px makes iPhones zoom in on it and stay zoomed) */
header .kit-greet { font-size:1rem; font-weight:700; line-height:1.2; margin:0; min-width:0; overflow-wrap:anywhere; color:var(--kit-on-header); }          /* "Hi <name>!" (kit 2.20.0) at the size and weight it had on the page, in the header's colour, on a line the header already has: never a row of its own */
header .brand:has(> .kit-greet) { display:grid; grid-template-columns:auto minmax(0, 1fr); gap:0 10px; align-items:center; }          /* everything on one line: the greeting under the app's name, the icon beside both */
header .brand:has(> .kit-greet) > img { grid-column:1; grid-row:1 / span 2; } header .brand:has(> .kit-greet) > h1 { grid-column:2; grid-row:1; align-self:end; } header .brand > .kit-greet { grid-column:2; grid-row:2; align-self:start; }
header .extras > .kit-greet { flex:1 1 0%; min-width:min(7rem, 100%); margin-right:auto; text-align:left; }          /* the buttons on a line of their own: the greeting first on it, at the left, the buttons at its right; a long name wraps in the room beside them, and only when it has less than 7rem do they move down: never cut */
@media (min-width:641px) { header.kit-greet-down .actions { flex:1 0 100%; } header.kit-greet-down .extras { flex:1 1 auto; } }          /* (the buttons under the name on a wider screen: their line runs the header's width, so the greeting is at its left) */
header .kit-greet-row { flex:1 0 100%; order:9; min-width:0; display:flex; align-items:center; justify-content:space-between; gap:10px; }          /* a page's own line with the greeting in it (its things at the greeting's right) */
header .kit-greet-row:has(> :not(.kit-greet, .hidden)) { flex-wrap:wrap; row-gap:6px; }          /* with something showing at its right, a name too long for the line wraps and that moves to the line below: a name is never cut short */
header .hidden, header .extras:not(:has(> :not(.hidden))) { display:none; }          /* hidden, and a line of page buttons with none showing, take no room (last, so it wins over the display rules above) */
/* section headings stick under the header while their section scrolls, stacked in order (the script marks them kit-stick and sets where each one stops) */
details > summary.kit-stick { position:sticky; top:var(--kit-stick-top, 0px); z-index:var(--kit-stick-z, 9); background:var(--kit-sticky-bg, var(--bg)); padding-top:4px; padding-bottom:4px; }
details > summary::after { content:""; display:table; clear:both; }          /* (a heading's own buttons, floated to its right, stay inside its row, stuck or not, and never hang into the words under it; kit 1.4.0) */
details > summary.kit-stuck { box-shadow:0 1px 0 var(--kit-stuck-line, var(--line, currentColor)); }          /* (kit 1.4.0: a heading that is stuck has an edge, so what scrolls under it plainly goes under it) */
details > summary.kit-stick .pill, details > summary.kit-stick .badge { display:inline-block; vertical-align:middle; }          /* (a badge in a heading is inside the heading's band, never hanging below it over the text) */
/* every field is as wide as its card (kit 1.4.0): a text box, dropdown or number box fills the width it is given, as its neighbours do, on any screen and either way up, and a long
   choice is cut only at its end (the list shows it whole). Fields side by side go in a .kit-fields row: they share the width and go one under the other when there is no room. A table's fields fit
   their column. Nothing else makes a field narrower (each app's tests check its stylesheets for it). */
:where(input:not([type=checkbox], [type=radio], [type=color], [type=range], [type=button], [type=submit], [type=reset], [type=file], [type=image]), select, textarea) { width:100%; max-width:100%; min-width:0; }
select { text-overflow:ellipsis; }
.kit-fields { display:flex; flex-wrap:wrap; gap:8px; } .kit-fields > * { flex:1 1 12rem; min-width:0; }
/* signing in (the script builds it in #kit-sign-in) and the test-mode banner (solid, bold, centred, in the line's colour; the page sets --kit-banner-ink, its text) */
#kit-sign-in .card { max-width:480px; margin-left:auto; margin-right:auto; }
/* the plain line when the server cannot be reached (the script adds it after the header, kit 2.6.0): it stays in view under the header, and sticky headings stack under it */
.kit-link { position:sticky; top:var(--kit-link-top, 0); z-index:99; background:var(--err-bg); color:var(--err-ink); text-align:center; font-size:.9rem; padding:8px max(16px, env(safe-area-inset-right)) 8px max(16px, env(safe-area-inset-left)); overflow-wrap:anywhere; }
.kit-link.hidden { display:none; }
html.kit-kept body > :not(#kit-link) { visibility:hidden; }          /* a page the browser kept: nothing of it shows until the server has answered and it has reloaded */
.kit-test-banner { background:var(--kit-line); color:var(--kit-banner-ink, var(--ink)); text-align:center; font-weight:700; font-size:.9rem; padding:8px 16px; }
/* the settings cog (first in the header's controls) and its panel: the same in every app; the page's tokens give the colours (--card, --ink, --line,
   --scrim, --dot-red; --kit-row-line for the rows' border, else --field or --line) */
#kit-cog { position:relative; padding:0 10px; }
#kit-cog svg { width:20px; height:20px; fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
#kit-cog-dot { position:absolute; top:-4px; right:-4px; width:11px; height:11px; border-radius:50%; background:var(--dot-red); box-shadow:0 0 0 2px var(--kit-header); }
.kit-panel-back { position:fixed; inset:0; top:var(--kit-header-foot, 0px); z-index:320; background:var(--bg); display:flex; align-items:flex-end; justify-content:center; padding-top:max(0px, env(safe-area-inset-top) - var(--kit-header-foot, 0px)); touch-action:none; overscroll-behavior:contain; }          /* (kit 1.4.1, found on an iPhone: it starts at the header's foot, so the header is never shaded; the script sets where. Kit 1.5.0: the page behind is covered, not shaded, as it was distracting) */
body > .kit-panel-back ~ :not(.kit-panel-back) { z-index:330; }          /* (kit 1.7.2) a card the page opens over the open panel (About This App, a row's card, a question) sits above it; a later one above that */
.kit-panel { background:var(--card); color:var(--ink); border-radius:0; width:100%; height:100%; display:flex; flex-direction:column; overflow:hidden; box-sizing:border-box; }          /* a phone: the whole space under the header */
.kit-panel-body { flex:1 1 auto; min-height:0; overflow:auto; overscroll-behavior:contain; -webkit-overflow-scrolling:touch; touch-action:pan-y; padding:14px max(16px, env(safe-area-inset-right)) 14px max(16px, env(safe-area-inset-left)); }
.kit-panel-foot { flex:none; border-top:1px solid var(--kit-row-line, var(--field, var(--line))); padding:10px max(16px, env(safe-area-inset-right)) calc(10px + env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left)); }          /* Save and Cancel, always in view at the foot */
.kit-panel .kit-tick { display:flex; align-items:center; gap:10px; min-height:44px; margin:4px 0; font-weight:600; } .kit-panel .kit-tick input { width:20px; height:20px; margin:0; flex:none; }
.kit-panel h2 { margin:4px 0 8px; font-size:1.2rem; color:var(--ink); text-transform:none; letter-spacing:normal; }          /* (kit 1.7.1: the panel's title is "Settings" in every app; a page's own heading style, such as the cards' red capitals, never reaches it) */ .kit-panel h3 { margin:12px 0 4px; font-size:1rem; } .kit-panel .kit-status { margin:4px 0 8px; line-height:1.4; }
.kit-panel .kit-buttons { display:flex; flex-wrap:wrap; gap:8px; } .kit-panel .kit-buttons button { min-height:44px; flex:1 1 9rem; }
.kit-panel .kit-own:empty { display:none; } .kit-panel .kit-own { margin-top:10px; }
.kit-row { display:flex; justify-content:space-between; align-items:center; gap:10px; width:100%; min-height:48px; text-align:left; padding:12px 14px; margin-top:10px; border:2px solid var(--kit-row-line, var(--field, var(--line))); border-radius:8px; background:var(--card); color:var(--ink); font:inherit; font-weight:600; cursor:pointer; }
.kit-row small { font-weight:400; opacity:.75; }
.kit-choice { display:flex; flex-direction:column; gap:4px; margin-top:10px; } .kit-choice > label, .kit-choice > .kit-choice-title { font-weight:600; } .kit-choice > small { opacity:.75; }          /* (kit 2.17.0) a choice on the panel itself (panel.choice): its field takes the kit's width, as on every card */
.kit-row-dot { display:inline-block; width:10px; height:10px; margin-left:8px; border-radius:50%; background:var(--err-ink); vertical-align:middle; }          /* (the panel's own red, seen in light and dark; the cog's dot sits on the header) */
#kit-version, .kit-version { margin:20px 0 0; padding:0 16px calc(12px + env(safe-area-inset-bottom)); text-align:center; font-size:.8rem; color:var(--grey, var(--ink)); } #kit-version:empty { display:none; }          /* (kit 1.7.3) the app's name and version at the foot of the page */
.kit-panel-foot .kit-version { margin:8px 0 0; padding:0; }          /* ... and under the panel's Save */
.kit-panel-msg:empty { display:none; } .kit-panel-msg { margin-bottom:8px; } .kit-panel .hidden { display:none; }
/* the scanner's level, in the settings of a page that plays it (kit 1.6.0) */
.meter { display:grid; grid-template-columns:max-content 1fr 4.6rem; align-items:center; gap:4px 10px; margin:10px 0 2px; font-size:.8rem; }
.meter .name { color:var(--grey); text-transform:uppercase; letter-spacing:.05em; font-weight:700; }
.meter .value { text-align:right; font-variant-numeric:tabular-nums; font-weight:700; }
.meter .track { position:relative; height:14px; border-radius:7px; overflow:hidden; background:linear-gradient(90deg, var(--ok) 0 70%, var(--highlight) 70% 90%, var(--danger) 90%); }
.meter .track.thin { height:8px; border-radius:4px; opacity:.85; }
.meter .cover { position:absolute; inset:0 0 0 auto; width:100%; background:var(--busy-bg); transform-origin:right center; transition:transform .12s linear; }
.meter .hold { position:absolute; top:0; bottom:0; width:2px; background:var(--ink); left:0; transition:left .12s linear; }
.meter .ticks { grid-column:2; display:flex; justify-content:space-between; color:var(--grey); font-size:.7rem; margin-top:-2px; }
@media (max-width:420px) { .meter { grid-template-columns:max-content 1fr 4rem; gap:4px 8px; } }
.kit-panel .kit-level-note { color:var(--grey); font-size:.85rem; margin:4px 0 0; }
@media (min-width:761px) { .kit-panel-back { align-items:center; padding:16px; } .kit-panel { border-radius:16px; width:min(32rem, 100%); height:auto; max-height:100%; border:1px solid var(--kit-row-line, var(--field, var(--line))); } }          /* a wider screen: a card in the middle */
@media (max-height:500px) { .kit-panel-back { padding:0; } .kit-panel { max-height:100%; height:100%; } }          /* a phone on its side, or the keyboard up: the panel uses the height there is */
/* ---- copy (CSS): every code card has a copy button (kit 1.7.0; the script's part of the same name puts it there): small, in the card's top right, kept clear of the code (the card
   leaves room for it), 44px to touch on a touch screen, a tick for 2 s once copied and, beside it, Copied or why it could not; hidden in print. A page with no kit carries
   this part as it is, from this line to its end line, and sets --card, --ink, --line and --dot-red. */
.kit-copy { position:relative; min-width:0; }
.kit-copy > code.kit-copy-block { padding-top:9px; padding-bottom:9px; padding-left:10px; border-radius:6px; line-height:1.4; background:color-mix(in srgb, var(--ink) 7%, transparent); }          /* (a line of code on its own is a small card; a pre keeps its page's own look) */
.kit-copy > .kit-copy-block { display:block; margin-top:0; margin-bottom:0; padding-right:40px; min-height:38px; white-space:pre-wrap; overflow-wrap:anywhere; overflow-x:visible; }          /* (kit 1.7.4, found at 375 wide: a long line wraps inside the card, so no line runs under the copy button; what is copied is the text exactly, line breaks only where it has them) */
.kit-copy-button { position:absolute; top:4px; right:4px; width:30px; height:30px; padding:0; display:inline-flex; align-items:center; justify-content:center; background:var(--card); color:var(--ink);
                   border:1px solid var(--line); border-radius:6px; cursor:pointer; opacity:.85; }
.kit-copy-button:hover, .kit-copy-button:focus-visible { opacity:1; }
.kit-copy-button svg { width:16px; height:16px; fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
@media (pointer:coarse) { .kit-copy-button { top:0; right:0; width:44px; height:44px; } .kit-copy > .kit-copy-block { padding-right:52px; min-height:44px; } }
.kit-copy-note:empty { display:none; } .kit-copy-note { display:block; text-align:right; font-size:.8rem; margin-top:2px; } .kit-copy-note.kit-copy-failed { color:var(--dot-red); font-weight:600; }
@media print { .kit-copy-button, .kit-copy-note { display:none; } }
/* ---- end of copy (CSS) ---- */
/* ---- layout (kit 2.0.0): what every page shares, the same in every app: cards and their closed height, sections and sub-sections, headings, spacing, fields,
   buttons, messages, the empty-list box and popups. A page adds only what is its own (its layout's widths and grids, its own content); it never sets a card's,
   a section's or a heading's size, padding or gap again. */
:root { --gap:16px; --kit-pad:18px; --kit-radius:12px; --kit-field-h:40px; --kit-head-size:1rem; --kit-head-line:26px; --kit-card-closed:72px; }          /* --gap: the one space between cards, tiles and the blocks inside a card */
.card { background:var(--card); border:1px solid var(--line); border-radius:var(--kit-radius); padding:var(--kit-pad); margin:0 0 var(--gap); min-width:0; }
.card-group[open] { padding-bottom:calc(var(--kit-pad) - var(--gap)); }          /* a card of cards: the last card's own gap makes its foot, so open or closed it is a card like the others */
.card h2, .modal-body h2 { font-family:var(--heading-font, inherit); font-size:var(--kit-head-size); margin:0 0 12px; color:var(--heading); text-transform:var(--heading-case, none); letter-spacing:var(--heading-spacing, normal); }          /* (a card's heading, and one inside a popup's body, kit 2.0.2; a popup's own title is in the ink, Title Case as written, kit 2.0.1) */
.modal-body h3 { font-family:var(--heading-font, inherit); font-size:.95rem; margin:20px 0 8px; color:var(--heading); text-transform:var(--heading-case, none); letter-spacing:var(--heading-spacing, normal); }          /* (a smaller heading in a popup's body, as a section's in a card, kit 2.0.2) */
.modal-body h2 { margin-top:20px; } .modal-body > :is(h2, h3):first-child { margin-top:0; }          /* (a heading in a popup's body has room above it, after the field before it; at the top, none: kit 2.0.4) */
.card summary { cursor:pointer; font-family:var(--heading-font, inherit); font-size:var(--kit-head-size); font-weight:700; color:var(--heading); text-transform:var(--heading-case, none); letter-spacing:var(--heading-spacing, normal); }
details.card > summary { line-height:var(--kit-head-line); padding-top:4px; padding-bottom:4px; }          /* a card's own heading: each line --kit-head-line high whatever the brand's font, so a closed card is --kit-card-closed (72px) in every app (kit 2.0.6); a long heading wraps, each extra line adding 26px, and is never cut short with an ellipsis (kit 2.0.7) */
details.card:not([open]) { min-height:var(--kit-card-closed); }          /* (and never less) */
details.card > summary > * { line-height:normal; vertical-align:middle; }          /* (what a card's heading holds, its buttons or a count, keeps its own height inside that one line) */
details[open] > summary { margin-bottom:12px; }
details.sub { margin:0; padding:10px 0 6px 16px; border-top:1px solid var(--line); }          /* a section inside a card: each level a step further in */
details.sub > summary { font-size:.95rem; }
details.sub.inner > summary { font-size:.9rem; }
label { display:block; font-weight:600; margin:12px 0 4px; }
:where(input:not([type=checkbox], [type=radio], [type=color], [type=range], [type=button], [type=submit], [type=reset], [type=file], [type=image]), select) { height:var(--kit-field-h); padding:0 10px; font:inherit; font-size:1rem; border:1px solid var(--field-line); border-radius:8px; background:var(--card); color:var(--ink); }
:where(textarea) { font:inherit; padding:10px; border:1px solid var(--field-line); border-radius:8px; background:var(--card); color:var(--ink); resize:vertical; }
:where(input, select, textarea):disabled { background:var(--disabled-bg); color:var(--disabled-ink); cursor:default; }          /* a field that cannot be changed yet (before Edit is pressed, kit 2.0.2) */
button { font:inherit; cursor:pointer; }
:is(button, a).primary, :is(button, a).secondary, :is(button, a).danger, :is(button, a).quiet { display:block; width:100%; padding:14px; font-size:1rem; font-weight:600; line-height:1.2; text-align:center; text-decoration:none; border-radius:8px; margin-top:14px; }
:is(button, a).primary { background:var(--accent); color:var(--on-accent); border:2px solid var(--accent); }          /* the same border as the others, so buttons side by side are the same height */
:is(button, a).primary:hover { background:var(--accent-strong); }
:is(button, a).secondary { background:var(--card); color:var(--link); border:2px solid var(--link); }
:is(button, a).danger { background:var(--err-bg); color:var(--err-ink); border:2px solid var(--danger); }          /* a button that deletes or changes something for real looks it, and never like Save (kit 2.0.3: a problem's tint and a red edge, beside a filled .primary and an outlined .secondary) */
:is(button, a).danger:hover, :is(button, a).danger:active { background:var(--danger); color:var(--on-danger); }          /* (--on-danger: the brand's text on its filled danger colour, kit 2.0.5) */          /* (filled only while it is pressed or pointed at) */
:is(button, a).quiet { background:var(--card); color:var(--ink); border:2px solid var(--field-line); }          /* a quiet one: Cancel, going back (kit 2.0.2; the old look of .danger) */
:is(button, a).small { width:auto; display:inline-block; padding:8px 14px; margin:0; font-size:.9rem; }          /* (a link can be a small button too, kit 2.0.2) */          /* buttons beside each other (Edit, Save, Cancel, Delete) */
button:disabled { opacity:.5; cursor:default; }
.muted { color:var(--grey); font-size:.9rem; }
.msg { padding:10px 12px; border-radius:8px; margin-top:12px; min-width:0; overflow-wrap:anywhere; }          /* (a long address in a message wraps inside its card) */
.msg.ok { background:var(--ok-bg); color:var(--ok-ink); }
.msg.err { background:var(--err-bg); color:var(--err-ink); }
.msg.busy { background:var(--busy-bg); color:var(--ink); display:flex; align-items:center; gap:10px; }
.msg.note { background:var(--note-bg); color:var(--ink); }          /* (kit 2.0.1) something to know, neither good nor bad */
.spinner { flex:none; width:18px; height:18px; border:3px solid var(--field-line); border-top-color:var(--accent); border-radius:50%; animation:kit-spin .8s linear infinite; }
@keyframes kit-spin { to { transform:rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation-duration:3s; } }
.empty { text-align:center; color:var(--grey); padding:28px 16px; }          /* a list with nothing in it says so, in one quiet box */
.kit-admin-view, header #logout { width:44px; padding:0; }          /* Admin View and Log Out (kit 2.14.0, 2.15.0): 44 px squares with the kit's shield and tick, and door and arrow (kit.js draws them); Admin View the same width on or off */
body:not(.kit-admin-page) .kit-admin-slot, body.kit-admin-page .kit-user-only,
body.kit-admin-page :is(main, main :has(.kit-admin-slot, .kit-admin-keep)) > :not(.kit-admin-slot, .kit-admin-keep, :has(.kit-admin-slot, .kit-admin-keep), #kit-version) { display:none !important; }          /* (kit 2.18.0) Admin View on is an Admin page of its own: in <main>, only the admin area and what the page keeps there; otherwise no admin area (Kit.adminPage) */
/* popups: a card over the page (.modal-back > .modal: a head with its title and buttons, a body that scrolls), and a sheet from the foot of the screen (.sheet-back > .sheet) */
  .modal-back { position:fixed; inset:0; height:100vh; height:100dvh; z-index:300; overscroll-behavior:contain; background:var(--scrim); display:flex; align-items:center; justify-content:center; padding:max(12px, env(safe-area-inset-top)) 12px 12px; }
  .modal { background:var(--card); color:var(--ink); border-radius:12px; width:min(46rem, 100%); max-height:88vh; display:flex; flex-direction:column; box-shadow:0 10px 40px var(--shadow-strong); }
  .modal-head { display:flex; align-items:center; justify-content:space-between; gap:12px; padding:14px 18px 10px; border-bottom:1px solid var(--line); }
  .modal-head h2 { margin:0; font-family:var(--heading-font, inherit); font-size:1.05rem; flex:1 1 0; min-width:0; overflow-wrap:anywhere; }          /* a long name wraps; the buttons never do */
  .modal-body { padding:8px 18px 16px; overflow:auto; -webkit-overflow-scrolling:touch; overscroll-behavior:contain; flex:1 1 auto; min-height:0; }
  .modal-actions { display:flex; gap:8px; flex-wrap:nowrap; flex:none; justify-content:flex-end; } .modal-actions button { white-space:nowrap; }
  .modal-back.top { z-index:310; } .modal.ask { width:min(26rem, 100%); }          /* a question is a small card: its height stops at the screen's like any card's, its words scroll and its buttons (in its head) stay in view (kit 2.0.3) */
  /* a phone (upright or on its side): the card is the whole screen. Its title and buttons are a bar that never moves (well below the notch, the status bar and the home bar), the details scroll
     beneath it, and nothing behind it can be scrolled (the page is held still while a card is open: see lockPage) */
  @media (max-width:760px), (max-height:520px) {
    .modal-back { padding:0; align-items:stretch; background:var(--card); touch-action:none; }
    .modal { width:100%; max-width:none; height:100%; max-height:none; border-radius:0; box-shadow:none; }
    .modal.ask { height:auto; max-height:calc(100% - 24px); align-self:center; margin:12px; width:calc(100% - 24px); border-radius:12px; }
    .modal-back.ask-back { background:var(--scrim); align-items:center; }
    .modal-head { flex:none; padding:calc(env(safe-area-inset-top, 0px) + 16px) calc(env(safe-area-inset-right, 0px) + 16px) 12px calc(env(safe-area-inset-left, 0px) + 16px); background:var(--card); }
    .modal-body { touch-action:pan-y; padding:10px calc(env(safe-area-inset-right, 0px) + 16px) calc(env(safe-area-inset-bottom, 0px) + 24px) calc(env(safe-area-inset-left, 0px) + 16px); }
  }
  @media (max-height:520px) { .modal-head { padding-top:calc(env(safe-area-inset-top, 0px) + 14px); padding-bottom:8px; } .modal-head h2 { font-size:.95rem; } }
  .modal-body .muted { font-size:.82rem; }
  .sheet-back { position:fixed; inset:0; touch-action:none; padding-top:calc(env(safe-area-inset-top) + 12px); background:var(--scrim); display:flex; align-items:flex-end; justify-content:center; z-index:20; }
  .sheet { touch-action:pan-y; background:var(--card); border-radius:16px 16px 0 0; width:min(32rem, 100%); max-height:80%; overflow:auto; overscroll-behavior:contain; -webkit-overflow-scrolling:touch; padding:14px calc(16px + env(safe-area-inset-right)) calc(16px + env(safe-area-inset-bottom)) calc(16px + env(safe-area-inset-left)); }
  .sheet-back.top { align-items:flex-start; padding-top:calc(env(safe-area-inset-top) + 6vh); } .sheet-back.top .sheet { border-radius:16px; max-height:calc(100% - 7vh); }
  @media (min-width:761px) { .sheet-back { align-items:center; } .sheet { border-radius:16px; } .sheet-back.top { align-items:flex-start; } }
.hidden { display:none !important; }          /* (last, so it wins) */
/* ---- fire cameras (CSS): the Fire Cameras section's window (kit 2.3.2; the script's part of the same name makes the frame in it): as wide as the card (the
   whole card on a phone) and exactly as long as the outside page, as measured (the script sets its height; 320 px until the frame is in it); the frame
   fills it, laid out at most 800 px wide and scaled up by the script to the window's width, so every camera is the same size and as large as the card allows,
   and the whole page shows as this page scrolls. Over it, until it is tapped, a clear shield whose one line, Tap to Use the Map and Cameras, keeps to the foot
   of the screen while the window is on it (sticky, so the window clips with overflow:clip, which keeps the screen as what it sticks to), so a swipe or a wheel
   moves this page and never the map; tapped, the shield goes (.kit-cameras-live). The credit under it, a long address wrapping. */
.kit-cameras-slot { position:relative; overflow:hidden; overflow:clip; min-height:320px; border:1px solid var(--line); border-radius:8px; background:var(--bg); }
.kit-cameras-frame { position:absolute; top:0; left:0; display:block; width:100%; height:100%; border:0; transform-origin:0 0; }
.kit-cameras-slot > .kit-cameras-shield { position:absolute; inset:0; z-index:1; display:flex; align-items:flex-end; justify-content:center; width:100%; height:100%; min-height:0; margin:0; padding:0 12px 12px; border:0; border-radius:0; background:transparent; color:var(--ink); cursor:pointer; }
.kit-cameras-hint { position:sticky; bottom:calc(12px + env(safe-area-inset-bottom)); display:inline-flex; align-items:center; min-height:44px; box-sizing:border-box; padding:8px 16px; border:1px solid var(--line); border-radius:8px; background:var(--card); color:var(--ink); font-weight:600; text-align:center; box-shadow:0 2px 10px var(--shadow); }
.kit-cameras-live > .kit-cameras-shield { display:none; }
.kit-cameras-credit { margin:10px 0 0; overflow-wrap:anywhere; }
@media (max-width:640px) {          /* a phone: the window takes the card's whole width, edge to edge, so the camera page has every pixel */
  .kit-cameras-slot { margin:0 calc(-1 * var(--kit-pad)); border-left:0; border-right:0; border-radius:0; }
}
/* ---- end of fire cameras (CSS) ---- */
/* ---- fire notices (CSS, kit 2.3.5; three equal buttons, kit 2.10.0): first in <main>, whose own sides keep clear of the notch, always side by side and the same width. Words always, never colour alone; long words wrap at their spaces and are never cut;
   not sticky, so they scroll away with the page. The Fire Danger Rating is a national scheme, so its colours are AFAC's own on-screen values (AFDRS Style Guidelines, updated 22 Jan 2025), the same in light and dark, and no brand file sets them. */
:root { --kit-afdrs-none:#ffffff; --kit-afdrs-moderate:#64bf30; --kit-afdrs-high:#fedd3a; --kit-afdrs-extreme:#f78100; --kit-afdrs-catastrophic:#ad0909; --kit-afdrs-ink:#000000; --kit-afdrs-on-catastrophic:#ffffff; }
.kit-fire { margin:0 0 var(--gap); min-width:0; container-type:inline-size; display:grid; grid-auto-flow:column; grid-auto-columns:minmax(0, 1fr); gap:4px; }
.kit-fire-row { min-width:0; position:relative; display:flex; align-items:center; justify-content:center; box-sizing:border-box; padding:4px 6px; border-radius:8px; font-size:.85rem; line-height:1.3; text-align:center; overflow-wrap:anywhere; text-decoration:none; }          /* (centred in every case, kit 2.5.0) */
.kit-fire-short { display:none; }          /* (a line's short words and where, where the row is narrow; the full words stay for a screen reader, kit 2.8.0) */
.kit-fire-brief, .kit-fire-where { display:block; }
.kit-fire-where { font-weight:400; }
@container (max-width:72rem) {
  .kit-fire-has-short .kit-fire-short { display:block; }
  .kit-fire-has-short .kit-fire-full { position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%); white-space:nowrap; }
}
.kit-fire-ban, .kit-fire-clear, [class*="kit-fire-fdr-"] { font-weight:700; }
.kit-fire-ban, a.kit-fire-ban { background:var(--dot-red); color:var(--on-accent); }
.kit-fire-clear, a.kit-fire-clear { background:var(--dot-green); background:color-mix(in srgb, var(--dot-green) 70%, black); color:var(--on-accent); }          /* (only a confirmed no ban or no period; darkened so the white words read, light and dark, kit 2.8.0) */
.kit-fire-fdr-none, a.kit-fire-fdr-none { background:var(--kit-afdrs-none); color:var(--kit-afdrs-ink); border:1px solid var(--kit-afdrs-ink); }          /* (the thin line shows it on a white card) */
.kit-fire-fdr-moderate, a.kit-fire-fdr-moderate { background:var(--kit-afdrs-moderate); color:var(--kit-afdrs-ink); }
.kit-fire-fdr-high, a.kit-fire-fdr-high { background:var(--kit-afdrs-high); color:var(--kit-afdrs-ink); }
.kit-fire-fdr-extreme, a.kit-fire-fdr-extreme { background:var(--kit-afdrs-extreme); color:var(--kit-afdrs-ink); }
.kit-fire-fdr-catastrophic, a.kit-fire-fdr-catastrophic { background:var(--kit-afdrs-catastrophic); color:var(--kit-afdrs-on-catastrophic); }
.kit-fire-plain { color:var(--grey); border:1px solid var(--line); }
a.kit-fire-plain { color:var(--link); }
@media (pointer:coarse) { a.kit-fire-row { min-height:44px; } }          /* (44 px to touch) */
/* ---- end of fire notices (CSS) ---- */
/* ---- a searchable choice (CSS, kit 2.9.0): the list sits in the card under its box, so it can never run past the card's edge or hide behind the keyboard's top row */
.kit-pick { min-width:0; }
.kit-pick-rows { margin-top:4px; max-height:min(16rem, 40dvh); overflow-y:auto; overscroll-behavior:contain; border:1px solid var(--field-line); border-radius:8px; background:var(--card); }
.kit-pick-row { display:flex; align-items:center; justify-content:space-between; gap:10px; min-height:44px; box-sizing:border-box; padding:8px 12px; cursor:pointer; color:var(--ink); overflow-wrap:anywhere; }
.kit-pick-row + .kit-pick-row { border-top:1px solid var(--line); }
.kit-pick-row:hover, .kit-pick-active { background:var(--bg); }
.kit-pick-code { flex:none; color:var(--grey); font-size:.85rem; }
.kit-pick-note { padding:8px 12px; color:var(--grey); font-size:.85rem; }
/* ---- end of a searchable choice (CSS) ---- */
/* ---- how two things are joined (CSS, kit 2.13.0): boxes and arrows in a row, wrapping at phone width, each app drawing it with its own elements:
   <div class="kit-flow" role="img" aria-label="in words"><span class="kit-flow-box">One</span><span class="kit-flow-arrow">joined by</span><span class="kit-flow-box">Two</span></div> */
.kit-flow { display:flex; flex-wrap:wrap; align-items:center; gap:6px 10px; margin:10px 0; min-width:0; }
.kit-flow-box { flex:0 1 auto; min-width:0; padding:8px 12px; border:1px solid var(--line); border-radius:8px; background:var(--card); color:var(--ink); font-weight:600; overflow-wrap:anywhere; }
.kit-flow-arrow { flex:0 1 auto; min-width:0; color:var(--grey); font-size:.9em; overflow-wrap:anywhere; }
/* ---- end of how two things are joined (CSS) ---- */
/* ---- end of the UI kit (CSS) ---- */
