/* Design System controls (Button, Field, select, date, file, Checkbox, Radio, Toggle, FileDrop, focus ring, touch targets).
   Values from docs/implementation/ui-fidelity/design-system/SPEC.md. Loaded after design-components.css.

   This layer is authoritative for control appearance. Family stylesheets (design-<family>.css) still own layout
   (width, flex, margin, display). Where they set a control's visual (height, padding, border, radius, colour) the
   rules below win through the `:not(#ds)` id boost, so a family rule cannot contradict the Design System again.
   No hover or pressed styling is drawn in Figma, so none is added here. */

:root { --ds-ring: 0 0 0 2px #ffffff, 0 0 0 4px #2447d6; }

/* ------------------------------------------------------------------ 1. Focus ring
   2px white gap + 2px accent ring outside the control (SPEC section 1). Buttons, links, tabs, nav items, summaries,
   scroll regions and every other focusable element use the same two layers. A Field draws the ring around the whole
   Field (label, box and hint, radii 4 and 2) instead of around the box. */
body:not(#ds) :focus-visible:focus-visible { outline: 0; box-shadow: var(--ds-ring); }
@media (forced-colors: active) { body:not(#ds) :focus-visible:focus-visible { outline: 2px solid CanvasText; outline-offset: 2px; } }
/* The native control inside a Field has no ring of its own: the Field draws it. */
body:not(#ds) :is(.field, .dialog label:not(.choice, .check), .ds-field) :is(input:is(:not([type]), [type="text"], [type="search"], [type="email"], [type="url"], [type="number"], [type="date"], [type="tel"], [type="password"], [type="time"], [type="month"], [type="datetime-local"]), select, textarea):focus-visible:focus-visible { box-shadow: none; }
body:not(#ds) :is(.field, .dialog label:not(.choice, .check), .ds-field):has(:is(input:is(:not([type]), [type="text"], [type="search"], [type="email"], [type="url"], [type="number"], [type="date"], [type="tel"], [type="password"], [type="time"], [type="month"], [type="datetime-local"]), select, textarea):focus-visible) { position: relative; }
body:not(#ds) :is(.field, .dialog label:not(.choice, .check), .ds-field):has(:is(input:is(:not([type]), [type="text"], [type="search"], [type="email"], [type="url"], [type="number"], [type="date"], [type="tel"], [type="password"], [type="time"], [type="month"], [type="datetime-local"]), select, textarea):focus-visible)::before {
  content: ""; position: absolute; inset: -2px; z-index: 1; pointer-events: none;
  border: 2px solid #ffffff; border-radius: 2px; box-shadow: 0 0 0 2px #2447d6;
}
/* Row cards sit in a rounded list that clips: the ring is drawn inside the card (same two layers, not clipped). */
body:not(#ds) :is(.cards, .card-list) :is(.card, .row-link):focus-visible:focus-visible { box-shadow: inset 0 0 0 2px #ffffff, inset 0 0 0 4px #2447d6; }
/* A click that opens an overlay moves focus without drawing the ring until a key is pressed (design-fidelity.js). */
body:not(#ds) [data-fid-quiet="1"]:focus-visible:focus-visible { box-shadow: none; }
body:not(#ds) :is(.field, .dialog label:not(.choice, .check), .ds-field):has([data-fid-quiet="1"]:focus-visible)::before { display: none; }

/* ------------------------------------------------------------------ 2. Button (Design System 3:18)
   Primary, Danger and Ghost have no border and are 34 high; Secondary and every disabled variant carry a 1px border
   and are 36 high. Radius 6, label 13/500 on 18, padding 8/16. Tablet and mobile: 44 high. */
body:not(#ds) :is(.primary, .secondary, .danger, .text-button, .close):not(.menu, .selector, .sr-only) {
  box-sizing: border-box; height: auto; min-height: 0; padding: 8px 16px;
  border: 0; border-radius: 6px; background: transparent; color: #2447d6;
  font: 500 13px/18px var(--font); letter-spacing: 0; text-align: center; text-decoration: none; text-transform: none;
  align-items: center; justify-content: center; opacity: 1;
}
:where(a.text-button, a.close, summary.text-button, summary.secondary) { display: inline-flex; }
/* A button label in a table cell never wraps: the cell grows, or the table scrolls. */
body:not(#ds) td :is(.primary, .secondary, .danger, .text-button):not(.menu, .selector) { white-space: nowrap; }
:where(summary.text-button, summary.secondary) { list-style: none; }
summary.text-button::-webkit-details-marker, summary.secondary::-webkit-details-marker { display: none; }
body:not(#ds) .primary:not(.menu, .selector, .sr-only) { background: #2447d6; color: #ffffff; }
body:not(#ds) .danger:not(.menu, .selector, .sr-only) { background: #a8201a; color: #ffffff; }
body:not(#ds) .secondary:not(.menu, .selector, .sr-only) { background: #ffffff; color: #1b1b1a; border: 1px solid #b5b3ab; }
body:not(#ds) :is(.primary, .secondary, .danger, .text-button, .close):is(:disabled, [aria-disabled="true"], .disabled):not(.menu, .selector, .sr-only) {
  background: #eeeeeb; border: 1px solid #d9d8d3; color: #6a6963; cursor: default;
}
@media (max-width: 1024px) {
  body:not(#ds) :is(.primary, .secondary, .danger, .text-button, .close):not(.menu, .selector, .sr-only) { height: 44px; min-height: 44px; }
}
/* Buttons of different drawn heights (34 borderless, 36 bordered) sit centred in a button row, as in Figma
   auto-layout, instead of being stretched to the tallest one. Zero specificity: a family rule wins. */
@media (min-width: 1025px) {
  :where(.panel-actions, .run-actions, .end-actions, .header-actions, .dialog-actions, .actions-end, .drawer-actions, .form-actions, .pager, .toolbar, .card-actions, .import-actions, .failed-actions, .locked-actions, .actions, .page-actions):where(:not(.actions-stack)) { align-items: center; }
}

/* ------------------------------------------------------------------ 3. Field (Design System 3:64)
   Label 12/500 #55544F, 4 gap, box 38 high, padding 8/12, radius 6, 1px #858480, value 14/400 on 20, hint 12/400 on
   16 #6A6963. Error: #A8201A box border and hint. Disabled: #EEEEEB fill, #6A6963 value. */
body:not(#ds) :is(input:is(:not([type]), [type="text"], [type="search"], [type="email"], [type="url"], [type="number"], [type="date"], [type="tel"], [type="password"], [type="time"], [type="month"], [type="datetime-local"]), select, textarea) {
  box-sizing: border-box; padding: 8px 12px; border: 1px solid #858480; border-radius: 6px;
  background-color: #ffffff; color: #1b1b1a; font: 400 14px/20px var(--font); letter-spacing: 0;
}
body:not(#ds) :is(input:is(:not([type]), [type="text"], [type="search"], [type="email"], [type="url"], [type="number"], [type="date"], [type="tel"], [type="password"], [type="time"], [type="month"], [type="datetime-local"]), select, textarea):not(textarea) { height: 38px; }
/* No placeholder style is drawn in Figma. Placeholder text uses the muted text token (#6A6963) so an empty field does not look filled. */
body:not(#ds) :is(input, textarea)::placeholder { color: var(--text-muted); opacity: 1; }
body:not(#ds) :is(input:is(:not([type]), [type="text"], [type="search"], [type="email"], [type="url"], [type="number"], [type="date"], [type="tel"], [type="password"], [type="time"], [type="month"], [type="datetime-local"]), select, textarea):disabled { background-color: #eeeeeb; color: #6a6963; -webkit-text-fill-color: #6a6963; border-color: #858480; cursor: default; }
body:not(#ds) :is(input, select, textarea)[aria-invalid="true"], body:not(#ds) :is(.field.error, .field[data-invalid]) :is(input:is(:not([type]), [type="text"], [type="search"], [type="email"], [type="url"], [type="number"], [type="date"], [type="tel"], [type="password"], [type="time"], [type="month"], [type="datetime-local"]), select, textarea) { border-color: #a8201a; }
body:not(#ds) :is(.field.error, .field[data-invalid]) .hint { color: #a8201a; }
body:not(#ds) .field .hint { margin: 0; font: 400 12px/16px var(--font); color: #6a6963; }
body:not(#ds) :is(.field.error, .field[data-invalid]) .hint { color: #a8201a; }
body:not(#ds) :is(input:is(:not([type]), [type="text"], [type="search"], [type="email"], [type="url"], [type="number"], [type="date"], [type="tel"], [type="password"], [type="time"], [type="month"], [type="datetime-local"]), select, textarea):user-invalid { border-color: #a8201a; }
/* Search fields are plain Fields: no native clear button, no spin buttons on number fields. */
body:not(#ds) input[type="search"] { -webkit-appearance: none; appearance: none; }
body:not(#ds) input[type="search"]::-webkit-search-cancel-button, body:not(#ds) input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; display: none; }
body:not(#ds) input[type="number"] { -moz-appearance: textfield; appearance: textfield; }
body:not(#ds) input[type="number"]::-webkit-inner-spin-button, body:not(#ds) input[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
/* The paste-a-list textarea next to a file drop is a normal Field (Figma draws no dashed textarea). */
body:not(#ds) .card-panel .field textarea { padding: 8px 12px; border: 1px solid #858480; background-color: #ffffff; }

/* ------------------------------------------------------------------ 4. Date field
   design-controls.js sets data-display ("28 Oct 2026") on every date input. The native input stays the source of
   truth: its calendar button is stretched over the whole field so a click anywhere opens the picker, and a keyboard
   user gets the native editable segments while typing (data-kb). */
@supports selector(::-webkit-datetime-edit) {
  body:not(#ds) input[type="date"][data-display] { position: relative; }
  body:not(#ds) input[type="date"][data-display]:not([data-kb])::-webkit-datetime-edit { opacity: 0; }
  body:not(#ds) input[type="date"][data-display]:not([data-kb])::before {
    content: attr(data-display); position: absolute; left: 12px; top: 8px; right: 12px; overflow: hidden;
    color: #1b1b1a; font: 400 14px/20px var(--font); white-space: nowrap; pointer-events: none;
  }
  body:not(#ds) input[type="date"][data-display]:disabled:not([data-kb])::before { color: #6a6963; }
  body:not(#ds) input[type="date"][data-display]::-webkit-calendar-picker-indicator {
    position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; padding: 0; opacity: 0; cursor: pointer;
  }
}

/* ------------------------------------------------------------------ 5. Select popup (progressive enhancement)
   The closed select is the native element styled as a Field. Fine pointers get this list instead of the native
   popup: popover recipe (radius 10, 1px #B5B3AB, shadow 0 8px 24px) with MenuItem rows (36 high, 8/12, radius 6,
   14/400). The selected row uses the popover option treatment (#E8EDFC fill, 14/500 #2447D6). INFERRED: Figma draws
   no select list, so the container padding (8) is not specified. */
.ds-menu {
  position: fixed; z-index: 100; box-sizing: border-box; display: flex; flex-direction: column; gap: 0;
  padding: 8px; overflow-y: auto; overscroll-behavior: contain;
  background: #ffffff; border: 1px solid #b5b3ab; border-radius: 10px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);
  font: 400 14px/20px var(--font); color: #1b1b1a;
}
.ds-menu[hidden] { display: none; }
.ds-opt {
  box-sizing: border-box; display: block; flex: none; height: 36px; padding: 8px 12px; border-radius: 6px; overflow: hidden; text-overflow: ellipsis;
  color: #1b1b1a; font: 400 14px/20px var(--font); white-space: nowrap; cursor: pointer; user-select: none;
}
.ds-opt[aria-selected="true"] { background: #e8edfc; color: #2447d6; font-weight: 500; }
.ds-opt[aria-disabled="true"] { color: #6a6963; cursor: default; }
.ds-menu[data-kb] .ds-opt.ds-active { box-shadow: inset 0 0 0 2px #2447d6; }
.ds-group { display: flex; flex-direction: column; flex: none; }
.ds-group-label { box-sizing: border-box; flex: none; padding: 8px 12px 4px; color: #6a6963; font: 500 12px/16px var(--font); }

/* ------------------------------------------------------------------ 6. Checkbox (3:106), Radio (3:114), Toggle (17:69)
   Native inputs are the visible control (appearance none); the span helpers some templates still carry next to a
   native input are hidden. Link or span look-alikes (.tick-box, .tick-link, .box, .radio-dot, .ring, span.radio)
   use the same visual. */
:where(input[type="checkbox"], input[type="radio"]) { position: relative; }
body:not(#ds) :is(input[type="checkbox"]:not([role="switch"]), input[type="radio"]) {
  -webkit-appearance: none; appearance: none; box-sizing: border-box; flex: none;
  width: 16px; height: 16px; min-width: 16px; min-height: 16px; margin: 0; padding: 0;
  border: 1px solid #858480; background: #ffffff; vertical-align: middle; cursor: pointer; opacity: 1;
  transform: none; box-shadow: none;
}
body:not(#ds) input[type="checkbox"]:not([role="switch"]) { border-radius: 4px; }
body:not(#ds) input[type="checkbox"]:not([role="switch"]):checked { background: #2447d6; border-color: #2447d6; }
body:not(#ds) input[type="checkbox"]:not([role="switch"]):checked::after {
  content: "\2713"; position: absolute; inset: -1px; display: grid; place-items: center; width: auto; height: auto;
  color: #ffffff; font: 500 12px/16px var(--font);
}
body:not(#ds) input[type="radio"] { border-radius: 50%; }
body:not(#ds) input[type="radio"]:checked { background: #2447d6; border-color: #2447d6; box-shadow: inset 0 0 0 3px #ffffff; }
body:not(#ds) :is(input[type="checkbox"]:not([role="switch"]), input[type="radio"]):focus-visible:focus-visible { box-shadow: var(--ds-ring); }
body:not(#ds) input[type="radio"]:checked:focus-visible:focus-visible { box-shadow: inset 0 0 0 3px #ffffff, var(--ds-ring); }
/* Disabled (not drawn in Figma): the Field disabled tokens. */
body:not(#ds) :is(input[type="checkbox"]:not([role="switch"]), input[type="radio"]):disabled { background: #eeeeeb; border-color: #858480; opacity: 1; cursor: default; }
body:not(#ds) input[type="checkbox"]:not([role="switch"]):disabled:checked { background: #6a6963; border-color: #6a6963; }
body:not(#ds) input[type="radio"]:disabled:checked { background: #6a6963; border-color: #6a6963; box-shadow: inset 0 0 0 3px #eeeeeb; }
/* Template helpers that used to draw the control: the native input is the control now. */
body:not(#ds) :is(.choice, .check-item, .switch-row, .toggle) > input + :is(.radio, .tick, .switch, .track) { display: none; }
body:not(#ds) :is(.choice, .check-item, .switch-row, .toggle) > input { position: relative; left: auto; top: auto; inset: auto; }
/* Toggle: 36x20 track, 16 knob 2px inside. Off #B5B3AB, on #2447D6. */
body:not(#ds) input[type="checkbox"][role="switch"] {
  -webkit-appearance: none; appearance: none; box-sizing: border-box; flex: none;
  width: 36px; height: 20px; min-width: 36px; margin: 0; padding: 0; border: 0; border-radius: 999px;
  background: #b5b3ab; vertical-align: middle; cursor: pointer; opacity: 1; transform: none; box-shadow: none;
}
body:not(#ds) input[type="checkbox"][role="switch"]::after {
  content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: #ffffff;
}
body:not(#ds) input[type="checkbox"][role="switch"]:checked { background: #2447d6; }
body:not(#ds) input[type="checkbox"][role="switch"]:checked::after { left: 18px; }
body:not(#ds) input[type="checkbox"][role="switch"]:focus-visible:focus-visible { box-shadow: var(--ds-ring); }
body:not(#ds) input[type="checkbox"][role="switch"]:disabled { background: #d9d8d3; cursor: default; }
body:not(#ds) input[type="checkbox"][role="switch"]:disabled:checked { background: #858480; }
/* Link and span look-alikes. */
body:not(#ds) :is(.tick-box, .tick-link, .box) {
  box-sizing: border-box; display: inline-grid; place-items: center; width: 16px; height: 16px; flex: none; margin: 0; padding: 0;
  border: 1px solid #858480; border-radius: 4px; background: #ffffff; color: #ffffff; font: 500 12px/16px var(--font); text-decoration: none;
}
body:not(#ds) :is(.tick-box.on, .tick-link.on, .box.on) { background: #2447d6; border-color: #2447d6; }
body:not(#ds) :is(.tick-box.on, .box.on)::after { content: "\2713"; }
body:not(#ds) :is(.radio, .radio-dot, .ring):not(input + *) {
  box-sizing: border-box; display: inline-block; width: 16px; height: 16px; flex: none; margin: 0; padding: 0;
  border: 1px solid #858480; border-radius: 50%; background: #ffffff; box-shadow: none;
}
body:not(#ds) :is(.radio.on, .radio-dot.on, .choice.selected .ring, .choice[aria-checked="true"] .radio):not(input + *) { background: #2447d6; border-color: #2447d6; box-shadow: inset 0 0 0 3px #ffffff; }

/* ------------------------------------------------------------------ 7. FileDrop (17:112)
   Padding 24, gap 8, radius 6, centred, 1px dashed #B5B3AB on #EEEEEB. Error: #FBE6E4 fill, #A8201A border and title.
   The native file input stays in the DOM, stretched and transparent over the drop zone, so it keeps keyboard focus
   and a click anywhere opens the picker. Selected looks like Empty (as drawn). */
body:not(#ds) .drop { position: relative; box-sizing: border-box; }
@media (min-width: 1025px) {
  body:not(#ds) .drop { border: 1px dashed #b5b3ab; border-radius: 6px; background: #eeeeeb; text-align: center; }
}
body:not(#ds) .drop input[type="file"] {
  position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; padding: 0; border: 0; opacity: 0; cursor: pointer; z-index: 1;
}
body:not(#ds) .drop:has(input[type="file"]:focus-visible) { box-shadow: var(--ds-ring); }
body:not(#ds) .drop input[type="file"]:focus-visible:focus-visible { box-shadow: none; }
body:not(#ds) .drop:is(.bad, .error, .failed-drop, :has(input[aria-invalid="true"])) { background: #fbe6e4; border-color: #a8201a; }
body:not(#ds) .drop:is(.bad, .error, .failed-drop, :has(input[aria-invalid="true"])) :is(strong, .drop-name) { color: #a8201a; }
/* Any other native file input (no drop zone around it) shows its button as a Secondary Button. */
body:not(#ds) input[type="file"]::file-selector-button {
  box-sizing: border-box; height: 36px; margin: 0 12px 0 0; padding: 8px 16px; border: 1px solid #b5b3ab; border-radius: 6px;
  background: #ffffff; color: #1b1b1a; font: 500 13px/18px var(--font); cursor: pointer;
}

/* ------------------------------------------------------------------ 8. Touch targets (tablet <= 1024, mobile <= 767)
   Primary touch controls are 44 high (buttons, section 2). Smaller visuals keep their drawn size and get a 44 x 44
   hit area: checkbox 16, radio 16, toggle 36 x 20, link look-alike boxes. Desktop keeps compact sizes. */
@media (max-width: 1024px) {
  body:not(#ds) :is(input[type="checkbox"]:not([role="switch"]), input[type="radio"])::before { content: ""; position: absolute; left: 50%; top: 50%; width: 44px; height: 44px; transform: translate(-50%, -50%); }
  body:not(#ds) input[type="checkbox"][role="switch"]::before { content: ""; position: absolute; inset: -12px -4px; }
  body:not(#ds) :is(.choice, .check, .check-item, .switch-row, .toggle, label:has(> input[type="checkbox"], > input[type="radio"])) { min-height: 44px; }
  /* Text links: the visible text keeps its size, a 44 high hit area surrounds it. */
  body:not(#ds) :is(a:not([class]), a.keyword, a.domain, a.extra, a.hint):not(.menu) { position: relative; }
  body:not(#ds) :is(a:not([class]), a.keyword, a.domain, a.extra, a.hint):not(.menu)::after {
    content: ""; position: absolute; left: -8px; right: -8px; top: 50%; height: 44px; transform: translateY(-50%);
  }
  /* A file drop that is drawn as plain text on tablet and mobile still gets a 44 high target. */
  body:not(#ds) .drop input[type="file"] { top: min(0px, calc((100% - 44px) / 2)); bottom: min(0px, calc((100% - 44px) / 2)); height: auto; }
  body:not(#ds) .tick-link { position: relative; }
  body:not(#ds) .tick-link::before { content: ""; position: absolute; left: 50%; top: 50%; width: 44px; height: 44px; transform: translate(-50%, -50%); }
}

