/* Qv2 base styles. EVERY value comes from a design token (a CSS custom property declared by the active theme in themes/<name>.css), so
   a theme is one swappable file and nothing here is hard-coded. Tints and shadows are DERIVED from the tokens with color-mix(), so a re-skin
   recolors them too. See the vault note "UI model: the current clinic portal and the v2 theme system" and v2/modules/frontend. */
*, *::before, *::after { box-sizing: border-box; }
html { color-scheme: light dark; -webkit-text-size-adjust: 100%; }
:root[data-mode="light"] { color-scheme: light; }
:root[data-mode="dark"] { color-scheme: dark; }
body {
  margin: 0; background: var(--color-bg); color: var(--color-text);
  font: var(--font-size-base)/1.55 var(--font-body); -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
h1, h2, h3 { font-family: var(--font-heading); font-weight: var(--font-weight-heading); line-height: 1.2; margin: 0 0 var(--space-3); letter-spacing: -.01em; }
h1 { font-size: var(--font-size-h1); } h2 { font-size: var(--font-size-h2); }
p { margin: 0 0 var(--space-3); }
a { color: var(--color-accent-text); text-underline-offset: .2em; }
h1, h2, h3, h4 { overflow-wrap: anywhere; }       /* a heading that names a record (billable_event.recorded) breaks inside the word rather than pushing the page sideways at 320 px (anywhere, not break-word: `.panel h2` is a flex row, and only anywhere lets its text item shrink) */
/* A link that stands on its own line beside a button (not inside a sentence) is a touch target of its own: at least 24 CSS pixels tall (WCAG 2.2 target size). */
a.tap { display: inline-block; padding-block: .35rem; }
button.as-link { background: none; border: 0; padding: 0; margin: 0; font: inherit; color: var(--color-accent-text); text-decoration: underline; text-underline-offset: .2em; cursor: pointer; }   /* a button that posts and reads as the link it replaced (a download whose filter holds a person's name: it cannot be in an address) */
:focus-visible { outline: 3px solid var(--color-focus); outline-offset: 2px; border-radius: var(--radius-sm); }
.muted { color: var(--color-text-muted); }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
[hidden] { display: none !important; }
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ---- icons: line = the text color around it, second tone = the theme accent (see templates/_sprite.html) */
.icon { width: 1.4em; height: 1.4em; flex: none; vertical-align: middle; }
.ic { fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.ic .tone { fill: var(--icon-tone); stroke: none; }
.icon.spin { animation: spin .8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---- the brand lockup */
.brand { display: inline-flex; align-items: center; gap: var(--space-2); font: var(--font-weight-heading) 1.5rem/1 var(--font-heading); letter-spacing: -.02em; color: var(--color-text); white-space: nowrap; }
.brand-mark { width: 2rem; height: 2rem; flex: none; }
.mark { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.mark-ring { stroke: currentColor; stroke-width: 3; }
.mark-pulse { stroke: var(--color-accent); stroke-width: 2.2; }
.mark-tail { stroke: var(--color-accent); stroke-width: 3; }
.mark-dot { fill: var(--color-accent); stroke: none; }
.brand-b { color: var(--color-accent); }
.brand.large { font-size: clamp(2.4rem, 6vw, 3.6rem); gap: var(--space-3); }
.brand.large .brand-mark { width: 1.15em; height: 1.15em; }

/* ---- buttons */
.btn {
  appearance: none; border: 1px solid transparent; border-radius: var(--radius-md); cursor: pointer; position: relative;
  padding: .7rem var(--space-4); font: var(--font-weight-button) var(--font-size-base)/1.2 var(--font-button);
  background: var(--color-accent); color: var(--color-on-accent);
  box-shadow: 0 1px 0 color-mix(in srgb, var(--color-on-accent) 25%, transparent) inset, 0 6px 16px -8px color-mix(in srgb, var(--color-accent) 70%, transparent);
  transition: background var(--motion) var(--ease), transform var(--motion) var(--ease), box-shadow var(--motion) var(--ease);
}
.btn:hover { background: var(--color-accent-hover); }
.btn:active { transform: translateY(1px); }
.btn.secondary { background: transparent; color: var(--color-text); border-color: var(--color-border); box-shadow: none; }
.btn.secondary:hover { background: var(--color-surface-2); }
.btn.block { display: flex; justify-content: center; align-items: center; gap: var(--space-2); width: 100%; }
.btn[aria-busy="true"] { pointer-events: none; opacity: .85; }
.iconbtn {
  appearance: none; display: inline-grid; place-items: center; width: 2.5rem; height: 2.5rem; border-radius: var(--radius-md); cursor: pointer;
  border: 1px solid transparent; background: transparent; color: inherit; padding: 0; font-size: 1.1rem;
  transition: background var(--motion) var(--ease);
}
.iconbtn:hover { background: color-mix(in srgb, currentColor 12%, transparent); }

/* ---- fields: a floating label (the label is always a real <label>) */
.field { display: block; position: relative; margin: 0 0 var(--space-4); }
.field > span { display: block; margin-bottom: var(--space-1); font-weight: 600; font-size: .9em; }
.field input, .field textarea {
  width: 100%; padding: .8rem var(--space-3); border-radius: var(--radius-md); border: 1px solid var(--color-border);
  background: var(--color-surface); color: var(--color-text); font: inherit;
  transition: border-color var(--motion) var(--ease), box-shadow var(--motion) var(--ease);
}
.field input::placeholder, .field textarea::placeholder { color: var(--color-text-muted); }
.field textarea { resize: vertical; min-height: 5.5rem; display: block; }
.field input:hover, .field textarea:hover { border-color: color-mix(in srgb, var(--color-text-muted) 60%, var(--color-border)); }
.field input:focus-visible, .field textarea:focus-visible { outline: none; border-color: var(--color-accent); box-shadow: 0 0 0 4px color-mix(in srgb, var(--color-accent) 22%, transparent); }
.field.float > span {
  position: absolute; left: var(--space-3); top: .85rem; margin: 0; padding: 0 .25rem; pointer-events: none; font-weight: 500; font-size: 1em;
  color: var(--color-text-muted); background: transparent; transform-origin: left top;
  transition: transform var(--motion) var(--ease), color var(--motion) var(--ease), background var(--motion) var(--ease);
}
.field.float input::placeholder, .field.float textarea::placeholder { color: transparent; }
.field.float input:focus ~ span, .field.float input:not(:placeholder-shown) ~ span, .field.float textarea:focus ~ span, .field.float textarea:not(:placeholder-shown) ~ span {
  transform: translateY(-1.45rem) scale(.82); color: var(--color-accent-text); background: var(--color-surface); font-weight: 600;
}
.field .reveal { position: absolute; right: .3rem; top: .3rem; color: var(--color-text-muted); }
.field .reveal[hidden] + input { padding-right: var(--space-3); }
.field.has-reveal input { padding-right: 3rem; }
.hint { margin: calc(-1 * var(--space-2)) 0 var(--space-4); color: var(--color-text-muted); font-size: .9em; }
.notice { padding: var(--space-3) var(--space-4); border-radius: var(--radius-md); background: var(--color-danger-soft); color: var(--color-danger-text); margin: 0 0 var(--space-4); }
.key { display: block; padding: var(--space-3); border-radius: var(--radius-md); background: var(--color-surface-2); border: 1px solid var(--color-border); word-break: break-all; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: .05em; user-select: all; }

/* ---- the skip link: first thing a keyboard user reaches */
.skip { position: absolute; left: var(--space-3); top: -4rem; z-index: 50; padding: var(--space-2) var(--space-4); border-radius: var(--radius-md); background: var(--color-accent); color: var(--color-on-accent); transition: top var(--motion) var(--ease); }
.skip:focus { top: var(--space-3); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; scroll-behavior: auto !important; }
  .icon.spin { animation: none; }
}

.notice.ok { background: var(--color-success-soft, var(--color-surface-2)); color: var(--color-success-text, var(--color-text)); }
.forgot { margin: var(--space-3) 0 0; text-align: center; }

/* ---- the environment banner (templates/_env_banner.html): a very thin red strip fixed to the foot of the window on every page of a system that is not production.
   The page keeps room for it (--env-banner-h: the stylesheet's estimate until env-banner.js measures it), so nothing is hidden behind it: the menu and the full-window
   layouts end above it, the page has padding below its last line, and a toast sits over it. In production none of this applies: there is no element and no attribute. */
html[data-env-banner] { --env-banner-h: 1.7rem; }
html[data-env-banner] body { padding-bottom: var(--env-banner-h); }
.env-banner {
  position: fixed; inset: auto 0 0 0; z-index: 100; display: flex; flex-wrap: wrap; align-items: center; gap: .1rem var(--space-3); padding: .2rem var(--space-3);
  background: var(--color-env-bg); color: var(--color-env-text); font-size: .72rem; line-height: 1.35;
}
.env-name { font-weight: 800; letter-spacing: .06em; white-space: nowrap; }
.env-facts { display: flex; flex-wrap: wrap; gap: 0 var(--space-2); margin: 0; padding: 0; list-style: none; }
.env-k { opacity: .85; }
.env-k::after { content: ":"; }
.env-v { font-weight: 600; }
@media (max-width: 40rem) {                                                   /* a phone: the name and the first three facts (database, sign-in, build), on two or three lines */
  html[data-env-banner] { --env-banner-h: 3.6rem; }
  .env-banner { font-size: .7rem; gap: 0 var(--space-2); }
  .env-facts { gap: 0 var(--space-2); }
  .env-facts li:nth-child(n+4) { display: none; }
}
@media (min-width: 40.01rem) {                                                /* a desktop: ONE line, always. The person's own line comes first and is never cut; the facts after it fade out at the right edge when the window is too narrow for all of them (the whole list is in the strip's title) */
  .env-banner { flex-wrap: nowrap; }
  .env-facts { flex-wrap: nowrap; flex: 1 1 0; min-width: 0; overflow: hidden; white-space: nowrap; -webkit-mask-image: linear-gradient(to right, currentcolor calc(100% - 2.5rem), transparent); mask-image: linear-gradient(to right, currentcolor calc(100% - 2.5rem), transparent); }
  .env-facts li { flex: none; }
}
@media print { .env-banner { display: none; } html[data-env-banner] body { padding-bottom: 0; } }
