/* ==========================================================
   VERYQUERY · design system
   Modern B2B / iOS-feel register. OLED near-black ground, pure
   white type, iOS system blue accent, Geist throughout, capsule
   pills, rounded surfaces, generous spacing, translucent
   materials.

   The universal layer for every veryquery surface: site,
   dashboard, admin, help, docs. Each surface loads this file
   from cdn.veryquery.dev (or .com in prod) and layers its own
   architecture on top in a local stylesheet.

   This file: tokens (:root), reset, typography base, .eyebrow,
   .prose, .btn*, .field* (form atoms), .checkbox, .switch,
   .dv-radio, .chip, form-layout primitives, utilities, ambient
   glow, scrollbar, reduced-motion + print overrides, .ds-container.

   Stores keep their own brand palette + typography, they're
   demo storefronts, not VeryQuery surfaces.
========================================================== */

:root {
  /* Tells the browser the page is dark-themed. Without this,
     Chrome/Edge/Safari render form controls with their light-mode
     UA chrome, which can override author background-color on
     <input>, scrollbars draw light, and autofill-yellow flashes
     bright. One line, fixes a class of "why is my input white?"
     bugs across the design system. */
  color-scheme: dark;

  /* ---------- Surfaces · elevation contract ----------
     OLED near-black ground with neutral-cool surfaces lifted via
     tint. Numbered elevation levels, higher index = brighter, so
     cards-on-panels-on-page reads as a coherent z-stack rather than
     guessing at colour names. Equal +0x0F (≈+15) RGB step per level
     gives a perceptually uniform climb from L0 to L6.

       --paper-0   L0  page background                       (darkest)
       --paper-1   L1  panels, primary surfaces, sticky alerts
       --paper-2   L2  raised items inside panels
                       (e.g. .summary-cell, .report-card,
                        .image-thumb, .preview boxes, base
                        chrome for form controls)
       --paper-3   L3  floating UI / hover-lift target for L2
                       (modals, dropdowns, popovers, form-control
                        hover state, controls raised inside an L2
                        card)
       --paper-4   L4  hover-lift target for L3
                       (e.g. a select inside a card, lifting on
                        hover from L3 base to L4)
       --paper-5   L5  reserved, hover-lift for L4 or rare deeper
                       nesting
       --paper-6   L6  reserved, top of the contract; use only
                       when there's a real surface stacking case
                                                            (brightest)

     Hover-lift convention: an interactive element at level N
     hovers up to N+1. Most elements never need to go above L3, 
     L4-L6 exist for elements that already start raised inside a
     card and still want a hover affordance.

     The `--bar` value below is a semi-transparent variant of L1
     (rgba(13, 13, 16, 0.72)) used by translucent backdrop-blurred
     bars (toolbars, sticky alerts). Kept as a literal because CSS
     can't read a token's components into rgba(). */
  --paper-0:       #060607;
  --paper-1:       #131316;
  --paper-2:       #26262C;
  --paper-3:       #35353D;
  --paper-4:       #44444C;
  --paper-5:       #53535B;
  --paper-6:       #62626A;
  --bar:           rgba(13, 13, 16, 0.72);

  /* ---------- Ink ----------
     Pure white at the top, neutral grays down. Body text uses
     --ink-soft; primary titles and big numerals use --ink. */
  --ink:           #FFFFFF;
  --ink-soft:      #E5E5EA;
  --ink-mid:       #A1A1A8;
  --ink-ghost:     #80808b;

  /* ---------- Hairlines ----------
     Paper at low opacity. Used sparingly, most structure comes
     from surface tinting, not borders. */
  --rule:          rgba(255, 255, 255, 0.07);
  --rule-soft:     rgba(255, 255, 255, 0.03);

  /* ---------- Contrast layers ----------
     Translucent black used as a halo / scrim under bright content
     (e.g. paint-order stroke on text drawn over the heatmap, or
     a backdrop scrim under floating UI). Theme-flips if we ever
     ship light mode. */
  --shade:         rgba(0, 0, 0, 0.65);

  /* ---------- Shadows ----------
     Elevation scale for floating surfaces (tooltips, popovers,
     modals). Token bundles offset + blur + color so a refactor
     ripples consistently. */
  --shadow-sm:     0 0.25rem 0.625rem rgba(0, 0, 0, 0.32);
  --shadow-md:     0 0.5rem 1.5rem rgba(0, 0, 0, 0.45);
  --shadow-lg:     0 1rem 2.5rem rgba(0, 0, 0, 0.55);

  /* ---------- Accent ----------
     iOS system blue (dark-mode variant). The single chromatic
     signal across CTAs, active states, brand mark fill, focus
     rings. */
  --accent:        #0A84FF;
  --accent-deep:   #3A9CFF;
  --accent-tint:   rgba(10, 132, 255, 0.16);

  /* Forest carry-over, maps to OK in the status scale */
  --forest:        #32D17A;

  /* ---------- Status palette ----------
     Saturated iOS system colors. `info` is purple to differentiate
     from the blue accent on the wheel. */
  --status-success:        #32D17A;
  --status-success-bg:     rgba(50, 209, 122, 0.16);
  --status-success-border: rgba(50, 209, 122, 0.30);
  --status-warning:        #FFC83D;
  --status-warning-bg:     rgba(255, 200, 61, 0.16);
  --status-warning-border: rgba(255, 200, 61, 0.30);
  --status-error:          #FF6058;
  --status-error-bg:       rgba(255, 96, 88, 0.16);
  --status-error-border:   rgba(255, 96, 88, 0.30);
  --status-info:           #0A84FF;
  --status-info-bg:        rgba(10, 132, 255, 0.16);
  --status-info-border:    rgba(10, 132, 255, 0.30);

  /* ---------- Event-group signal colors (--eg-*) ----------
     THE single source for the color of every change-event signal, so the map dots,
     the filter chips, the feed, the histograms, and the landing pages all speak one
     palette. Anything that shows a signal color reads a var below (CSS uses var()
     directly; the map/canvas layers resolve it in JS by name, see egColor()). Permits
     is indigo, deliberately off the brand accent blue. The first six are the canonical
     event GROUPS; the rest are the landing pages' finer distress/opportunity categories.
     Organized by polarity: POSITIVE / opportunity signals are cool (green, indigo, cyan);
     NEGATIVE / distress signals are warm (amber, orange, red). None use the brand blue. */
  --eg-permits:      #32D17A; /* positive: green */
  --eg-sales:        #2D6BF5; /* positive: royal blue (clear of purple and the brand azure) */
  --eg-cofo:         #64D2FF; /* positive: cyan */
  --eg-violations:   #FF7A2E; /* negative: red-orange (between demolitions and distress) */
  --eg-demolitions:  #FFD633; /* negative: yellow-amber */
  --eg-distress:     #FF3B30; /* negative: pure red (was coral) */
  --eg-landuse:      #64D2FF;
  --eg-tax:          #FFC83D;
  --eg-foreclosure:  #FF375F;
  --eg-vacancy:      #D9730D;
  --eg-inspections:  #BF5AF2;
  --eg-demolition:   #8E8E93;
  --eg-other:        #80808b;
  --status-pending:        #A1A1A8;
  --status-pending-bg:     rgba(255, 255, 255, 0.06);
  --status-pending-border: rgba(255, 255, 255, 0.12);

  /* ---------- Badge backgrounds ----------
     Inline pill tints. Slightly more saturated than the panel
     `--status-*-bg` set since they sit on the body ground rather
     than under a headline. */
  --badge-neutral-bg: rgba(255, 255, 255, 0.06);
  --badge-success-bg: rgba(50, 209, 122, 0.18);
  --badge-warning-bg: rgba(255, 200, 61, 0.18);
  --badge-danger-bg:  rgba(255, 96, 88, 0.18);
  --badge-info-bg:    rgba(10, 132, 255, 0.18);
  --badge-pending-bg: rgba(255, 255, 255, 0.08);
  --badge-unknown-bg: rgba(255, 255, 255, 0.06);

  /* ---------- Radius ----------
     Rounded scale. Capsule pills use --radius-full; cards use
     --radius-lg; buttons use --radius-md; inputs --radius-md. */
  --radius-sm:   0.375rem;
  --radius-md:   0.625rem;
  --radius-lg:   0.875rem;
  --radius-full: 9999px;

  /* ---------- Type ----------
     Geist does all the work. --font-mono is reserved for IDs,
     tabular numerals, and small caption-style chips. --font-wordmark
     is the brand mark face and nothing else, referenced only by
     .app__mark, so the wordmark family can move without touching
     display or body. Currently Geist, at a heavier weight than the
     UI uses. */
  --font-display:  "Geist", -apple-system, "SF Pro Display", BlinkMacSystemFont, "Helvetica Neue", sans-serif;
  --font-body:     "Geist", -apple-system, "SF Pro Text", BlinkMacSystemFont, "Helvetica Neue", sans-serif;
  --font-mono:     "Geist Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --font-wordmark: "Geist", -apple-system, BlinkMacSystemFont, sans-serif;

  /* ---------- Type scale ---------- */
  --t-3xs: 0.625rem;
  --t-2xs: 0.6875rem;
  --t-xs:  0.75rem;
  --t-sm:  0.8125rem;
  --t-base:0.875rem;
  --t-md:  0.9375rem;
  --t-lg:  1.0625rem;
  --t-xl:  1.25rem;
  --t-2xl: 1.625rem;
  --t-3xl: 2.125rem;
  --t-4xl: 2.75rem;
  --t-5xl: 3.5rem;
  --t-6xl: 4.5rem;

  /* Badge typography, sans, not mono caps */
  --badge-font-size:      0.6875rem;
  --badge-padding:        0.1875rem 0.625rem;
  --badge-letter-spacing: 0;

  /* ---------- Space ---------- */
  --s-1: 0.25rem;
  --s-2: 0.5rem;
  --s-3: 0.75rem;
  --s-4: 1rem;
  --s-5: 1.5rem;
  --s-6: 2rem;
  --s-7: 3rem;
  --s-8: 4.5rem;
  --s-9: 6.5rem;
  --s-10: 9rem;
  --s-11: 12rem;

  /* ---------- Structure ---------- */
  --container: 82.5rem;
  --gutter:    clamp(1.25rem, 4vw, 3rem);
  --rule-w:    1px;

  /* ---------- Motion ---------- */
  --ease:        cubic-bezier(0.2, 0, 0, 1);
  --ease-out:    cubic-bezier(0.2, 0, 0, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --dur-fast: 120ms;
  --dur:      200ms;
  --dur-slow: 380ms;
  --dur-1: 200ms;
  --dur-2: 380ms;
  --dur-3: 600ms;
  --dur-4: 900ms;
}

/* ==========================================================
   RESET + BASE
========================================================== */
* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: var(--s-7); }
html, body { height: 100%; }
body {
  font-family: var(--font-body);
  font-size: var(--t-base);
  line-height: 1.45;
  color: var(--ink-soft);
  background: var(--paper-0);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  letter-spacing: -0.003em;
  font-feature-settings: "ss01", "cv11", "cv09";
  overflow-x: clip;
  position: relative;
}

img, svg { display: block; max-width: 100%; }
/* Form-control reset. Font/color inheritance is wanted on every form
   control. The background/border wipe is scoped to <button> only, 
   inputs/selects/textareas get their chrome from the safety-net and
   `select` rules later in this file; a blanket reset here would
   wipe them out (and used to). */
button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
input, textarea { cursor: text; }
textarea { resize: none; }
a { color: inherit; text-decoration: none; color: var(--accent);}
ul, ol { list-style: none; }
em { font-style: italic; }

/* ==========================================================
   AMBIENT GLOW
   Soft radial in the top-left, tinted by the accent. Anchors
   chrome to a "light source" without being decorative. Pinned
   to the viewport, sits behind everything.
========================================================== */
html::before {
  content: "";
  position: fixed;
  top: -12.5rem;
  left: -12.5rem;
  width: 37.5rem;
  height: 37.5rem;
  background: radial-gradient(circle, rgba(10, 132, 255, 0.08), transparent 70%);
  pointer-events: none;
  z-index: 0;
}

/* ==========================================================
   TYPOGRAPHY BASE
========================================================== */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1.1;
  color: var(--ink);
}
h1 { font-size: clamp(2.5rem, 6vw, var(--t-5xl)); }
h2 { font-size: clamp(2rem, 5vw, var(--t-4xl)); }
h3 { font-size: clamp(1.25rem, 2.4vw, var(--t-xl)); }

p { color: var(--ink-soft); }

.prose p + p { margin-top: var(--s-4); }
.prose p {
  font-size: clamp(1rem, 1.1vw, var(--t-md));
  line-height: 1.6;
  color: var(--ink-soft);
  max-width: 60ch;
}
.prose em {
  font-style: italic;
  color: var(--ink);
}
.prose strong { font-weight: 600; color: var(--ink); }
.prose h2 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--t-2xl);
  letter-spacing: -0.01em;
  line-height: 1.15;
  margin: var(--s-7) 0 var(--s-2);
  color: var(--ink);
}
.prose h3 {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--t-md);
  letter-spacing: 0;
  margin: var(--s-5) 0 var(--s-2);
  color: var(--ink);
}
.prose ul, .prose ol {
  margin: 0 0 var(--s-4);
  padding-left: 1.25rem;
  max-width: 60ch;
  color: var(--ink-soft);
  line-height: 1.6;
}
.prose li { margin: 0.25rem 0; }
.prose li > ul, .prose li > ol { margin-bottom: 0; }
.prose code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  background: var(--paper-2);
  padding: 0.1em 0.35em;
  border-radius: var(--radius-sm);
  color: var(--ink-soft);
}
.prose pre {
  font-family: var(--font-mono);
  font-size: 0.85em;
  line-height: 1.55;
  background: var(--paper-2);
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius-sm);
  padding: 0.9rem 1.1rem;
  margin: 0 0 var(--s-4);
  max-width: 60ch;
  overflow-x: auto;
  white-space: pre;
  color: var(--ink-soft);
}
.prose pre code {
  background: transparent;
  padding: 0;
  border-radius: 0;
  font-size: inherit;
}

/* ==========================================================
   EYEBROW
   Quiet sans label, no mono-caps "instrument tag" treatment.
   Used as a small section context label.
========================================================== */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-mid);
}
.eyebrow__sigil { display: none; }  /* legacy § sigil retired */

/* ==========================================================
   BUTTONS
========================================================== */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4375rem;
  padding: 0.5rem 0.875rem;
  font-family: var(--font-body);
  font-size: var(--t-sm);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.05);
  box-shadow: inset 0 0 0 1px var(--rule);
  border: 0;
  border-radius: var(--radius-md);
  cursor: pointer;
  position: relative;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), transform var(--dur-fast) var(--ease);
}
.btn:hover { background: rgba(255, 255, 255, 0.10); }
.btn:active { transform: scale(0.97); }
.btn__arrow {
  font-family: var(--font-body);
  font-size: 1em;
  transition: transform var(--dur) var(--ease);
}
.btn:hover .btn__arrow { transform: translateX(2px); }

.btn--primary {
  background: var(--accent);
  color: var(--ink);
  box-shadow: 0 0 0 1px rgba(10, 132, 255, 0.40), 0 0.375rem 1rem rgba(10, 132, 255, 0.28);
}
.btn--primary:hover {
  background: var(--accent-deep);
  color: var(--ink);
}

/* Secondary, translucent raised chip with a hairline inset ring. This is
   the everyday neutral; it's visually identical to a bare .btn (kept as the
   explicit semantic name, not a separate look). Pairs with .btn--primary. */
.btn--secondary {
  background: rgba(255, 255, 255, 0.05);
  color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--rule);
}
.btn--secondary:hover {
  background: rgba(255, 255, 255, 0.10);
  color: var(--ink);
}

/* Danger, neutral chip with error-colored label at rest (inherits the base
   ring); fills solid red on hover, ring following the fill so no grey
   hairline shows over the red. */
.btn--danger {
  background: rgba(255, 255, 255, 0.05);
  color: var(--status-error);
}
.btn--danger:hover {
  background: var(--status-error);
  color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--status-error);
}

.btn--small { padding: 0.375rem 0.6875rem; font-size: var(--t-xs); }
.btn[disabled], .btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

/* ==========================================================
   HONEYPOT (off-screen, accessible)
========================================================== */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ==========================================================
   FORM FIELDS
   .field is the universal form atom: label + input/select/
   textarea + optional hint + optional error. Rounded chrome,
   subtle fill, accent ring on focus.
========================================================== */
.field {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  font-family: var(--font-body);
}
.field--wide { grid-column: 1 / -1; }
.field--inline {
  flex-direction: row;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.field--inline .field__k { min-width: 8rem; flex: 0 0 auto; }
.field--inline input,
.field--inline select { width: auto; flex: 0 1 auto; }
.field--inline input[type="number"] { flex: 0 0 9rem; }
.field--inline input[type="text"],
.field--inline input[type="email"],
.field--inline input[type="url"],
.field--inline input[type="search"] { flex: 1 1 12rem; }
.field--inline .field__hint { flex: 1 1 auto; }
.field__hint--mono {
  font-family: var(--font-mono);
  font-style: normal;
  font-size: var(--t-xs);
  letter-spacing: 0;
}

.field__k {
  font-family: var(--font-body);
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-mid);
}
.field__k--required::before {
  content: "*";
  color: var(--accent);
  margin-right: 0.3em;
}

/* Text input + textarea chrome, applies to every input/textarea
   regardless of surface or wrapping class. Layout (sizing) comes
   from the parent: `.field` gives form-column sizing, the shared
   `.toolbar` (components.css) gives flex sizing, bare inputs
   auto-size to content.
   `:where()` keeps specificity at zero so any explicit class can
   still override. The :not() chain excludes input types that have
   their own UA chrome (checkbox/radio via `.checkbox` / `.dv-radio`,
   button-like inputs, hidden, range with its own thumb styling). */
:where(input:not([type="checkbox"],[type="radio"],[type="file"],[type="submit"],[type="button"],[type="reset"],[type="image"],[type="hidden"],[type="range"],[type="color"]),
       textarea) {
  /* `appearance: none` strips UA chrome on `<input type="search">`
     (Safari renders a rounded "searchfield" with its own background
     that ignores ours) and normalizes a few other minor UA quirks
     across browsers. Author rules below then own the look fully. */
  -webkit-appearance: none;
  appearance: none;
  font-family: var(--font-body);
  font-size: var(--t-sm);
  color: var(--ink);
  padding: 0.5rem 0.75rem;
  /* Form-control elevation. Defaults to L2 base / L3 hover+focus,
     matching <select> chrome so every control reads at the same
     elevation. Inputs nested inside already-raised surfaces (e.g. a
     card inside a panel where the card itself sits at L3) override
     both vars on an ancestor so the contrast lift still works:
        .deep-card { --field-bg: var(--paper-3);
                     --field-bg-hover: var(--paper-4); }
     Variables inherit, so every form control under the override
     element, and any compound control that consumes the same
     vars (e.g. .copy-input), picks up the deeper levels. */
  background-color: var(--field-bg, var(--paper-2));
  border: 0;
  border-radius: var(--radius-md);
  outline: none;
  transition: background-color var(--dur) var(--ease);
}
:where(input:not([type="checkbox"],[type="radio"],[type="file"],[type="submit"],[type="button"],[type="reset"],[type="image"],[type="hidden"],[type="range"],[type="color"]),
       textarea)::placeholder { color: var(--ink-ghost); }
:where(input:not([type="checkbox"],[type="radio"],[type="file"],[type="submit"],[type="button"],[type="reset"],[type="image"],[type="hidden"],[type="range"],[type="color"]),
       textarea):hover:not(:disabled) { background-color: var(--field-bg-hover, var(--paper-3)); }
:where(input:not([type="checkbox"],[type="radio"],[type="file"],[type="submit"],[type="button"],[type="reset"],[type="image"],[type="hidden"],[type="range"],[type="color"]),
       textarea):focus {
  background-color: var(--field-bg-hover, var(--paper-3));
}
:where(input:not([type="checkbox"],[type="radio"],[type="file"],[type="submit"],[type="button"],[type="reset"],[type="image"],[type="hidden"],[type="range"],[type="color"]),
       textarea):disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

/* `.field`-wrapped inputs/textareas: full-column width, invalid
   border, textarea height. Chrome inherits from the base rule above. */
.field input,
.field textarea {
  width: 100%;
  resize: none;
}
.field input.is-invalid,
.field textarea.is-invalid { border: 1px solid var(--status-error); }
.field textarea {
  min-height: 6rem;
  line-height: 1.5;
}

/* ==========================================================
   SELECT · global chrome
   Applied to EVERY <select> element and to .select-trigger
   (a button that simulates a select, used by the header
   org/property switcher and the user menu, which open custom
   popovers instead of a native option list). All select-like
   controls share one visual contract:
     · L2 paper background, lifts to L3 on hover/focus
     · no border, no focus ring, the paper lift is the focus indicator
     · same chevron SVG, same colour, same position
     · same radius, same font weight
   .field-wrapped selects fill their form column; bare or
   toolbar selects auto-size to their content. */
select,
.select-trigger {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  display: inline-flex;
  align-items: center;
  font-family: var(--font-body);
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--ink);
  /* L2 fill so the control pops above panels (L1) and the page (L0)
     alike. Hover/focus lift one step further to L3, the paper lift
     is the focus indicator; no border. */
  background-color: var(--paper-2);
  border: 0;
  border-radius: var(--radius-md);
  padding: 0.5rem 2rem 0.5rem 0.75rem;
  outline: none;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23E5E5EA' fill='none' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.75rem center;
  background-size: 0.625rem 0.375rem;
  transition: background-color var(--dur) var(--ease);
}
select:hover:not(:disabled),
.select-trigger:hover:not(:disabled) {
  background-color: var(--paper-3);
}
select:focus,
select:focus-visible,
.select-trigger:focus-visible,
.select-trigger.is-open {
  background-color: var(--paper-3);
}
select:disabled,
.select-trigger:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}
select.is-invalid,
.select-trigger.is-invalid {
  border: 1px solid var(--status-error);
}

/* .field-wrapped selects fill the form column instead of
   auto-sizing to their content. */
.field select { width: 100%; }

.field__hint {
  font-family: var(--font-body);
  font-style: normal;
  font-size: var(--t-xs);
  color: var(--ink-mid);
  line-height: 1.4;
}
.field__error {
  font-family: var(--font-body);
  font-size: var(--t-xs);
  letter-spacing: 0;
  color: var(--status-error);
  min-height: 1em;
}
/* Empty until a message is set (via textContent); collapse so it claims no
   space (and no flex gap) in a flex-gap form or body when there's no error. */
.field__error:empty { display: none; }

/* Range slider, dark restyle, white thumb, accent fill */
.field input[type="range"] {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  width: 100%;
  height: 1.125rem;
  background: transparent;
  cursor: pointer;
  display: block;
  padding: 0;
  border: 0;
  --slider-fill: 50%;
}
.field input[type="range"]::-webkit-slider-runnable-track {
  height: 0.25rem;
  border-radius: var(--radius-full);
  background:
    linear-gradient(to right,
      var(--accent) 0%, var(--accent) var(--slider-fill),
      var(--paper-2) var(--slider-fill), var(--paper-2) 100%);
}
.field input[type="range"]::-moz-range-track {
  height: 0.25rem;
  border-radius: var(--radius-full);
  background: var(--paper-2);
  border: 0;
}
.field input[type="range"]::-moz-range-progress {
  height: 0.25rem;
  border-radius: var(--radius-full);
  background: var(--accent);
}
.field input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 1.125rem;
  height: 1.125rem;
  margin-top: -0.4375rem;
  border-radius: var(--radius-full);
  background: #FFFFFF;
  border: 0;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease);
}
.field input[type="range"]::-moz-range-thumb {
  width: 1.125rem;
  height: 1.125rem;
  border-radius: var(--radius-full);
  background: #FFFFFF;
  border: 0;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
  cursor: pointer;
}
.field input[type="range"]:hover::-webkit-slider-thumb,
.field input[type="range"]:focus-visible::-webkit-slider-thumb {
  transform: scale(1.08);
}
.field input[type="range"]:focus-visible::-moz-range-thumb {
  transform: scale(1.08);
}
.field .slider-ends {
  display: flex;
  justify-content: space-between;
  font-family: var(--font-body);
  font-size: var(--t-xs);
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-mid);
  margin-top: 0.25rem;
}
.field .field__k .field__value-badge {
  display: inline-block;
  margin-left: 0.5rem;
  padding: 1px 0.5rem;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  color: var(--accent);
  background: var(--accent-tint);
  border-radius: var(--radius-sm);
  min-width: 1.5em;
  text-align: center;
}

/* ==========================================================
   CHECKBOX
========================================================== */
.checkbox {
  display: inline-grid;
  grid-template-columns: auto 1fr;
  column-gap: 0.5rem;
  align-items: center;
  cursor: pointer;
  font-family: var(--font-body);
  font-size: var(--t-sm);
  color: var(--ink);
  line-height: 1.3;
  user-select: none;
}
.checkbox input[type="checkbox"] {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
}
.checkbox__box {
  width: 1em;
  height: 1em;
  border: 1px solid var(--rule);
  background: var(--paper-1);
  border-radius: 0.25rem;
  flex-shrink: 0;
  position: relative;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.checkbox input[type="checkbox"]:checked + .checkbox__box {
  background: var(--accent);
  border-color: var(--accent);
}
.checkbox input[type="checkbox"]:checked + .checkbox__box::after {
  content: "";
  position: absolute;
  inset: 2px;
  background: #FFFFFF;
  clip-path: polygon(20% 50%, 45% 75%, 85% 25%, 75% 15%, 45% 55%, 30% 40%);
}
.checkbox input[type="checkbox"]:focus-visible + .checkbox__box {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.checkbox input[type="checkbox"]:disabled + .checkbox__box {
  opacity: 0.55;
  cursor: not-allowed;
}

/* ==========================================================
   SWITCH
========================================================== */
.switch {
  position: relative;
  display: inline-block;
  width: 2.6rem;
  height: 1.4rem;
  vertical-align: middle;
  cursor: pointer;
}
.switch input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.switch__track {
  position: absolute;
  inset: 0;
  background: var(--paper-2);
  border: 0;
  border-radius: var(--radius-full);
  transition: background var(--dur) var(--ease);
}
.switch__track::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: calc(1.4rem - 0.25rem);
  height: calc(1.4rem - 0.25rem);
  background: #FFFFFF;
  border: 0;
  border-radius: var(--radius-full);
  transition: transform var(--dur) var(--ease);
  box-shadow: 0 1px 0.1875rem rgba(0, 0, 0, 0.4);
}
.switch input:checked + .switch__track { background: var(--accent); }
.switch input:checked + .switch__track::after { transform: translateX(1.2rem); }
.switch input:focus-visible + .switch__track {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.switch input:disabled + .switch__track {
  opacity: 0.55;
  cursor: not-allowed;
}

/* ==========================================================
   VQ-RADIO + VQ-FORM
   Modal-internal radio stack with built-in row separators.
========================================================== */
.dv-radio {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 0.75rem;
  align-items: start;
  padding: 0.625rem 0;
  cursor: pointer;
  font-family: var(--font-body);
}
.dv-radio input[type="radio"] {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
}
.dv-radio__label {
  position: relative;
  padding-left: 1.5rem;
  font-size: var(--t-sm);
  color: var(--ink);
}
.dv-radio__label::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.18rem;
  width: 1rem;
  height: 1rem;
  border: 1px solid var(--ink-ghost);
  background: transparent;
  border-radius: 50%;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.dv-radio input[type="radio"]:checked + .dv-radio__label::before {
  background: var(--accent);
  border-color: var(--accent);
  box-shadow: inset 0 0 0 0.1875rem var(--paper-0);
}
.dv-radio input[type="radio"]:focus-visible + .dv-radio__label::before {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.dv-radio__hint {
  grid-column: 2;
  padding-left: 1.5rem;
  font-size: var(--t-xs);
  color: var(--ink-mid);
  line-height: 1.4;
}
.dv-form > * + * { margin-top: 1rem; }

/* ==========================================================
   CHIP, capsule pill
========================================================== */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.375rem 0.875rem;
  font-family: var(--font-body);
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--ink-mid);
  background: var(--paper-1);
  border: 0;
  border-radius: var(--radius-full);
  cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.chip:hover { background: var(--paper-2); color: var(--ink); }
.chip--active {
  background: var(--ink);
  color: var(--paper-0);
}
/* Active chip keeps its inverse styling on hover, without this,
   `.chip:hover` (specificity 0,2,0) wins over `.chip--active`
   (0,1,0) and the active chip looks like a normal inactive one
   while hovered. Slight desaturate to --ink-soft signals "click to
   deselect" without flipping the visual semantic. */
.chip--active:hover { background: var(--ink-soft); color: var(--paper-0); }

/* ==========================================================
   FORM LAYOUT PRIMITIVES
========================================================== */
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
@media (max-width: 40em) { .form-grid { grid-template-columns: 1fr; } }

.form-stack { display: flex; flex-direction: column; gap: 1rem; }
.form-stack--lg    { gap: 1.25rem; }
.form-stack--tight { gap: 0.75rem; }

.form-section { display: flex; flex-direction: column; gap: 0.75rem; }
.form-section__head { display: flex; flex-direction: column; gap: 0.25rem; }
.form-section__title {
  font-family: var(--font-body);
  font-size: var(--t-md);
  font-weight: 600;
  color: var(--ink);
}
.form-section__lede { color: var(--ink-mid); }

.form-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  padding-top: 1rem;
  margin-top: 1.25rem;
  border-top: 1px solid var(--rule-soft);
}
.form-actions__detach { margin-right: auto; }

/* ==========================================================
   INLINE TEXT PRIMITIVES
========================================================== */
.hint {
  font-family: var(--font-body);
  font-size: var(--t-xs);
  letter-spacing: 0;
  color: var(--ink-mid);
}
.hint--tight { letter-spacing: 0; }

.inline-code {
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  background: var(--paper-1);
  padding: 2px 0.375rem;
  border-radius: var(--radius-sm);
  color: var(--ink-soft);
  letter-spacing: 0;
}

/* ==========================================================
   UTILITIES
========================================================== */
.mono         { font-family: var(--font-mono); }
.muted        { color: var(--ink-mid); }
.text-success { color: var(--status-success); }
.text-danger  { color: var(--status-error); }
.text-accent  { color: var(--accent); }

.text-3xs { font-size: var(--t-3xs); }
.text-2xs { font-size: var(--t-2xs); }
.text-xs  { font-size: var(--t-xs); }
.text-sm  { font-size: var(--t-sm); }
.text-md  { font-size: var(--t-md); }
.text-lg  { font-size: var(--t-lg); }
.text-xl  { font-size: var(--t-xl); }

.text-right { text-align: right; }
.nums-right { text-align: right; font-variant-numeric: tabular-nums; }

.mt-1 { margin-top: var(--s-1); }
.mt-2 { margin-top: var(--s-2); }
.mt-3 { margin-top: var(--s-3); }
.mt-4 { margin-top: var(--s-4); }
.mt-5 { margin-top: var(--s-5); }
.mt-6 { margin-top: var(--s-6); }
.mb-1 { margin-bottom: var(--s-1); }
.mb-2 { margin-bottom: var(--s-2); }
.mb-3 { margin-bottom: var(--s-3); }
.mb-4 { margin-bottom: var(--s-4); }
.mb-5 { margin-bottom: var(--s-5); }
.mb-6 { margin-bottom: var(--s-6); }

.hidden    { display: none !important; }
.is-hidden { display: none; }

/* ==========================================================
   SCROLLBAR, dark, neutral
========================================================== */
::-webkit-scrollbar { width: 0.625rem; height: 0.625rem; }
::-webkit-scrollbar-track {
  background: var(--paper-0);
  border-radius: var(--radius-sm);
}
::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.10);
  border-radius: var(--radius-sm);
  border: 2px solid var(--paper-0);
}
::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.20); }

/* ==========================================================
   REDUCED MOTION
========================================================== */
@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;
  }
  [data-reveal] { opacity: 1; transform: none; }
}

/* ==========================================================
   PRINT
========================================================== */
@media print {
  html::before { display: none; }
  * { color: #000 !important; background: #fff !important; }
}

/* ==========================================================
   GENERIC CONTAINER
========================================================== */
.ds-container {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
