/*
 * Buttons (INVENTORY §5): push button (BS_PUSHBUTTON / BS_DEFPUSHBUTTON), check box, radio button, group box,
 * static label. Measured values: SPEC.md §2.3–2.5, §3.6; Marlett glyphs as Windows draws them (DrawFrameControl).
 * State comes from native attributes (disabled, :checked, :indeterminate, :focus) plus data-pressed set by
 * js/components/button.js; .is-active / .is-focus force the same rules for the Gallery (PROMPT.md §7).
 */

/* ── Push button ─────────────────────────────────────────────────────────────────────────────────── */
.w2k-button {
  position: relative;
  display: inline-block;
  vertical-align: top;
  width: var(--metric-button-width);
  height: var(--metric-button-height);
  padding: 0;
  border: 0;
  border-radius: 0;
  background: var(--color-control-face);
  color: var(--sys-btn-text);
  font: inherit;
  box-shadow: var(--edge-push);
  outline: none;
  cursor: inherit;
  -webkit-appearance: none;
  appearance: none;
}
/* Label: positioned by button.js — left = floor((width − text width) / 2), line top 4px (SPEC.md §3.6). A label wider
   than the button (a wider font, a larger scale — button.js marks it data-cut) is held 4px inside both edges and cut
   with "..." instead of running out of it; one that fits is not clipped at all. */
.w2k-button__label {
  position: absolute;
  top: var(--metric-button-label-top);
  left: var(--label-left, 0);
  white-space: pre;
  pointer-events: none;
}
.w2k-button__label[data-cut] {
  max-width: calc(100% - 8px);
  overflow-x: clip;   /* across only: the mnemonic underline and descenders still show below the line */
  text-overflow: ellipsis;
}

/* Heights (extension, user 2026-10-10): the standard 23px, a field's (level with the edit or combo beside it) and a mini
   one; the label kept centred (its 4px top in 23px, less a pixel per 2px fewer). */
.w2k-button--field {
  height: var(--metric-button-height-field);
  --metric-button-label-top: round(down, var(--metric-button-height-field) / 2 - 7.5px, 1px);
}
.w2k-button--mini {
  height: var(--metric-button-height-mini);
  --metric-button-label-top: round(down, var(--metric-button-height-mini) / 2 - 7.5px, 1px);
}

/* A glyph in a push button (an owner-drawn button's picture — Sound Recorder's transport): the win2k bitmap as a mask
   in --glyph-color (the button's text colour by default), embossed when disabled (DSS_DISABLED: ButtonShadow over a
   white copy 1px right and down — on the label, as a mask clips the element's own filter); a theme's icon for the
   bitmap (the <img>, resolved by the icon set) drawn instead, centred.
   <span class="w2k-button__glyph"><img src="x.png" alt=""></span> — placed by the application; button.js masks it by
   the image (--glyph). */
.w2k-button__glyph {
  position: absolute;
  display: grid;
  place-items: center;
  background: var(--glyph-color, currentColor);
  -webkit-mask: var(--glyph) no-repeat;
  mask: var(--glyph) no-repeat;
}
.w2k-button__glyph > img { visibility: hidden; }
.w2k-button__glyph:has(> img[data-icon-theme]) { -webkit-mask: none; mask: none; background: none; }
.w2k-button__glyph > img[data-icon-theme] { visibility: visible; }
:is(.w2k-button:disabled, .w2k-button[aria-disabled="true"]) .w2k-button__glyph { --glyph-color: var(--color-disabled-text); }
:is(.w2k-button:disabled, .w2k-button[aria-disabled="true"]) > .w2k-button__label:has(> .w2k-button__glyph) { filter: drop-shadow(1px 1px 0 var(--color-disabled-emboss)); }
:is(.w2k-button:disabled, .w2k-button[aria-disabled="true"]) > .w2k-button__label:has(> .w2k-button__glyph > img[data-icon-theme]) { filter: none; }

/* Default frame: the declared default button, or the focused push button (which takes over the default look),
   unless another push button in the same dialog has focus. */
.w2k-button[data-default],
.w2k-button:focus, .w2k-button.is-focus {
  box-shadow: var(--edge-control-default);
}
:where([role="dialog"], form, .w2k-dialog):has(.w2k-button:focus) .w2k-button[data-default]:not(:focus) {
  box-shadow: var(--edge-push);
}

/* Focus rectangle inside the button, 4px from the outer edge (measured on the logon message box). */
.w2k-button:focus::after, .w2k-button.is-focus::after {
  content: "";
  position: absolute;
  inset: var(--metric-button-focus-inset);
  background: var(--focus-rect-image);
  pointer-events: none;
}
html[data-cues="hidden"] .w2k-button:focus:not(.is-focus)::after { display: none; }

/* Pressed (mouse or Space): black frame + ButtonShadow frame, label 1px right and down. knowledge — QUESTIONS Q5. */
.w2k-button[data-pressed], .w2k-button.is-active {
  box-shadow: var(--edge-control-pressed);
}
.w2k-button[data-pressed] .w2k-button__label, .w2k-button.is-active .w2k-button__label {
  transform: translate(1px, 1px);
}

/* A disabled button has the plain edge — except the dialog's default button, which keeps its black frame (Run's OK
   while the field is empty, measured). */
.w2k-button:is(:disabled, [aria-disabled="true"]):not([data-default]) {
  box-shadow: var(--edge-push);
}
/* An owner-drawn button's frame (data-edge="raised" — Calculator's keys, Sound Recorder's transport; measured): the
   raised control edge (win2k: EDGE_RAISED, 3D Light outside) in every state but pressed — no default frame when
   focused —, sunk while pressed (knowledge); its focus rectangle 3px in, starting with a dot (Sound Recorder). */
.w2k-button[data-edge="raised"]:not([data-pressed], .is-active) { box-shadow: var(--edge-control-raised); }
.w2k-button[data-edge="raised"]:is([data-pressed], .is-active) { box-shadow: var(--edge-sunken); }
.w2k-button[data-edge="raised"] {
  --metric-button-focus-inset: 3px 4px 4px 3px;
  --focus-rect-image:
    repeating-linear-gradient(to right, var(--color-focus-dot) 0 1px, transparent 1px 2px) 0 0 / 100% 1px no-repeat,
    repeating-linear-gradient(to right, var(--color-focus-dot) 0 1px, transparent 1px 2px) 0 100% / 100% 1px no-repeat,
    repeating-linear-gradient(to bottom, var(--color-focus-dot) 0 1px, transparent 1px 2px) 0 0 / 1px 100% no-repeat,
    repeating-linear-gradient(to bottom, var(--color-focus-dot) 0 1px, transparent 1px 2px) 100% 0 / 1px 100% no-repeat;
}
.w2k-button:disabled .w2k-button__label, .w2k-button[aria-disabled="true"] .w2k-button__label {
  color: var(--color-disabled-text);
  text-shadow: 1px 1px 0 var(--color-disabled-emboss);
}

/* ── Check box and radio button ──────────────────────────────────────────────────────────────────── */
.w2k-check, .w2k-radio {
  position: relative;
  display: inline-block;
  vertical-align: top;
  height: var(--line-height-ui);
  padding-left: var(--check-text-offset);
  white-space: pre;
  color: var(--sys-btn-text);
}
.w2k-check { --check-text-offset: var(--metric-checkbox-text-offset); }
.w2k-radio { --check-text-offset: var(--metric-radio-text-offset); }

/* The native input stays for semantics and keyboard; it is transparent and covers the whole control. */
.w2k-check > input, .w2k-radio > input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: inherit;
}

.w2k-check__box {
  position: absolute;
  left: 0;
  top: 0;
  width: var(--metric-checkbox-size);
  height: var(--metric-checkbox-size);
  background: var(--sys-window);
  box-shadow: var(--edge-sunken);
}
/* Check mark: Marlett "a" at 13 ppem (matches the reference 7×7 mark exactly), in ButtonText. */
.w2k-check__box::after {
  content: "a";
  position: absolute;
  left: 0;
  top: var(--metric-checkbox-mark-top);
  font: var(--font-glyph-check);
  color: var(--sys-window-text);
  visibility: hidden;
}
.w2k-check > input:checked + .w2k-check__box::after,
.w2k-check > input:indeterminate + .w2k-check__box::after { visibility: visible; }
/* A check box in a list item (a check-box list, list-view state images — measured on Regional Options' language groups
   and Display Properties › Web): the box alone, its state from the item's aria-checked, framed 2px in WindowText.
   <div role="option" aria-checked="true"><span class="w2k-check__box" data-list aria-hidden="true"></span>…</div> */
.w2k-check__box:where([data-list]) { box-shadow: inset 0 0 0 2px var(--sys-window-text); color: var(--sys-window-text); }
[aria-checked="true"] > .w2k-check__box:where([data-list])::after { visibility: visible; }

/* Indeterminate (BS_3STATE): gray mark on the checkerboard dither. knowledge */
.w2k-check > input:indeterminate + .w2k-check__box {
  background: var(--color-control-face);
}
.w2k-check > input:indeterminate + .w2k-check__box::before {
  content: "";
  position: absolute;
  inset: 2px;
  background: var(--sys-btn-hilight);
  -webkit-mask: var(--pattern-dither-mask) 0 0 / var(--pattern-dither-size) repeat;
  mask: var(--pattern-dither-mask) 0 0 / var(--pattern-dither-size) repeat;
}
.w2k-check > input:indeterminate + .w2k-check__box::after { color: var(--sys-btn-shadow); }

/* Radio: six Marlett glyphs at 12 ppem in system colors — n interior, j/k outer, l/m inner, i dot (measured). */
.w2k-radio__glyphs {
  position: absolute;
  left: 0;
  top: var(--metric-radio-top);
  width: var(--metric-radio-size);
  height: var(--metric-radio-size);
  font: var(--font-glyph-radio);
}
.w2k-radio__glyphs > i { position: absolute; left: 0; top: 0; font-style: normal; }
.w2k-radio__glyphs > .n { color: var(--sys-window); }
.w2k-radio__glyphs > .j { color: var(--sys-btn-shadow); }
.w2k-radio__glyphs > .k { color: var(--sys-btn-hilight); }
.w2k-radio__glyphs > .l { color: var(--sys-btn-dk-shadow); }
.w2k-radio__glyphs > .m { color: var(--sys-btn-light); }
.w2k-radio__glyphs > .i { color: var(--sys-window-text); visibility: hidden; }
.w2k-radio > input:checked + .w2k-radio__glyphs > .i { visibility: visible; }

/* Pressed (mouse down on the control) and disabled: interior ButtonFace; disabled marks in GrayText. knowledge */
.w2k-check[data-pressed] .w2k-check__box, .w2k-check.is-active .w2k-check__box,
.w2k-check > input:disabled + .w2k-check__box { background: var(--color-surface); }
.w2k-radio[data-pressed] .w2k-radio__glyphs > .n, .w2k-radio.is-active .w2k-radio__glyphs > .n,
.w2k-radio > input:disabled + .w2k-radio__glyphs > .n { color: var(--color-surface); }
.w2k-check > input:disabled + .w2k-check__box::after,
.w2k-radio > input:disabled + .w2k-radio__glyphs > .i { color: var(--sys-gray-text); }
.w2k-check:has(> input:disabled) > .w2k-check__text,
.w2k-radio:has(> input:disabled) > .w2k-check__text {
  color: var(--color-disabled-text);
  text-shadow: 1px 1px 0 var(--color-disabled-emboss);
}

/* Focus rectangle around the label text, 1px outside it. knowledge (inset to confirm) */
.w2k-check__text { position: relative; }
.w2k-check > input:focus ~ .w2k-check__text::after, .w2k-check.is-focus > .w2k-check__text::after,
.w2k-radio > input:focus ~ .w2k-check__text::after, .w2k-radio.is-focus > .w2k-check__text::after {
  content: "";
  position: absolute;
  inset: 0 -1px;
  background: var(--focus-rect-image);
  pointer-events: none;
}
html[data-cues="hidden"] :is(.w2k-check, .w2k-radio):not(.is-focus) > input:focus ~ .w2k-check__text::after { display: none; }

/* ── Group box (BS_GROUPBOX): etched frame, caption breaks the top line ──────────────────────────── */
.w2k-groupbox {
  position: relative;
  margin: 0;
  padding: var(--metric-groupbox-padding);
  border: 0;
  min-inline-size: 0;
}
.w2k-groupbox::before {
  /* Etched frame: shadow line, hilight line 1px inside (EDGE_ETCHED). */
  content: "";
  position: absolute;
  inset: var(--metric-groupbox-frame-top) 0 0 0;
  box-shadow:
    inset -1px -1px var(--sys-btn-hilight), inset 1px 1px var(--sys-btn-shadow),
    inset -2px -2px var(--sys-btn-shadow), inset 2px 2px var(--sys-btn-hilight);
  pointer-events: none;
}
.w2k-groupbox > legend {
  position: absolute;
  top: 0;
  left: var(--metric-groupbox-caption-left);
  padding: 0 var(--metric-groupbox-caption-gap);
  margin-left: calc(-1 * var(--metric-groupbox-caption-gap));
  background: var(--color-surface);
  color: var(--sys-btn-text);
  white-space: pre;
}
.w2k-groupbox:disabled > legend {
  color: var(--color-disabled-text);
  text-shadow: 1px 1px 0 var(--color-disabled-emboss);
}

/* ── Static text / label ─────────────────────────────────────────────────────────────────────────── */
.w2k-label { color: var(--sys-btn-text); white-space: pre; }
/* Disabled: embossed (DSS_DISABLED), the emboss clipped to the line — no highlight under the descenders' last row
   (measured on Display Properties and Power Options). */
.w2k-label[aria-disabled="true"] { color: var(--color-disabled-text); text-shadow: 1px 1px 0 var(--color-disabled-emboss); clip-path: inset(0 -2px 0 0); }

/* ── Push-like (BS_PUSHLIKE) and flat (BS_FLAT) check boxes and radio buttons — knowledge, no reference ─────────
   Push-like: drawn as a push button; checked = pressed (sunken) with the checkerboard dither, label +1,+1.
   Flat: the box / circle frame is a single 1px ButtonShadow line. */
:where(.w2k-check, .w2k-radio).w2k-pushlike {
  width: var(--metric-button-width);
  height: var(--metric-button-height);
  padding: 0;
  background: var(--color-control-face);
  box-shadow: var(--edge-push);
}
.w2k-pushlike > .w2k-check__box, .w2k-pushlike > .w2k-radio__glyphs { display: none; }
.w2k-pushlike > .w2k-check__text {
  position: absolute;
  top: var(--metric-button-label-top);
  left: var(--label-left, 0);
}
.w2k-pushlike:has(> input:checked), .w2k-pushlike.is-active {
  box-shadow: var(--edge-sunken);
}
.w2k-pushlike:has(> input:checked)::before {
  content: "";
  position: absolute;
  inset: 2px;
  background: var(--sys-btn-hilight);
  -webkit-mask: var(--pattern-dither-mask) 0 0 / var(--pattern-dither-size) repeat;
  mask: var(--pattern-dither-mask) 0 0 / var(--pattern-dither-size) repeat;
  pointer-events: none;
}
.w2k-pushlike:has(> input:checked) > .w2k-check__text,
.w2k-pushlike.is-active > .w2k-check__text { transform: translate(1px, 1px); }
.w2k-pushlike > input:focus ~ .w2k-check__text::after, .w2k-pushlike.is-focus > .w2k-check__text::after { inset: -1px -2px; }

.w2k-check.w2k-flat .w2k-check__box { box-shadow: inset 0 0 0 1px var(--sys-btn-shadow); }
.w2k-radio.w2k-flat .w2k-radio__glyphs > :is(.j, .k, .l, .m) { color: var(--sys-btn-shadow); }
.w2k-radio.w2k-flat .w2k-radio__glyphs > :is(.l, .m) { color: var(--sys-window); }
