/* The native input stays in the DOM -- it carries the state, the keyboard * behaviour and the accessibility -- but it is invisible; .cx-check-box is what * you see. Hiding it with opacity rather than display:none keeps it focusable. */ .cx-check-input, .cx-radio-input, .cx-toggle-input { position: absolute; opacity: 0; width: 0; height: 0; margin: 0; } .cx-check { display: inline-flex; } .cx-check-box { width: 16px; height: 16px; flex: none; border: var(--bw) solid var(--line); border-radius: var(--r-2); background: var(--elev-2); display: inline-flex; align-items: center; justify-content: center; transition: background var(--dur-1) var(--ease-standard), border-color var(--dur-1) var(--ease-standard); } .cx-check-box::after { content: ""; width: 9px; height: 5px; border-left: 2px solid var(--on-accent); border-bottom: 2px solid var(--on-accent); transform: rotate(-45deg) translateY(-1px) scale(.6); opacity: 0; transition: opacity var(--dur-1) var(--ease-standard), transform var(--dur-1) var(--ease-standard); } .cx-check-input:checked + .cx-check-face .cx-check-box { background: var(--accent); border-color: var(--accent); } .cx-check-input:checked + .cx-check-face .cx-check-box::after { opacity: 1; transform: rotate(-45deg) translateY(-1px) scale(1); } .cx-check-input:indeterminate + .cx-check-face .cx-check-box { background: var(--accent); border-color: var(--accent); } .cx-check-input:indeterminate + .cx-check-face .cx-check-box::after { opacity: 1; width: 8px; height: 0; border-bottom: 2px solid var(--on-accent); border-left: 0; transform: none; } .cx-check-input:focus-visible + .cx-check-face .cx-check-box { border-color: var(--accent); box-shadow: var(--focus-ring); } .cx-check-input:disabled + .cx-check-face .cx-check-box { opacity: var(--disabled-opacity); } /* The input sits alongside its label, not inside it -- see choice.js. The row * is the positioning context; the .cx-check-face label is what you click. */ .cx-check-row, .cx-radio, .cx-toggle-row { position: relative; } /* Room around the words. A checkbox in this app is a switch with a sentence under it, not a tick in a list: at 4px the label and its explanation sat hard against the top and bottom of the card they are in, and a hint that wrapped to two lines had nowhere to wrap into. */ .cx-check-face { display: flex; align-items: flex-start; gap: var(--sp-4); cursor: pointer; padding: var(--sp-4) 0; } .cx-toggle-face { align-items: center; justify-content: space-between; gap: var(--sp-6); } /* min-inline-size, or a long word in a hint pushes the row wider than the panel it is in instead of wrapping. */ .cx-check-text { display: flex; flex-direction: column; gap: 2px; min-inline-size: 0; } .cx-check-label { font-size: var(--fs-4); line-height: var(--lh-4); color: var(--text); } .cx-checklist { display: flex; flex-direction: column; max-height: 200px; overflow-y: auto; border: var(--bw) solid var(--line); border-radius: var(--r-3); padding: var(--sp-3) var(--sp-4); } .cx-radio-group { display: flex; gap: var(--sp-4); } .cx-radio-vertical { flex-direction: column; gap: var(--sp-2); } .cx-radio-dot { width: 16px; height: 16px; flex: none; border-radius: var(--r-pill); border: var(--bw) solid var(--line); background: var(--elev-2); display: inline-flex; align-items: center; justify-content: center; } .cx-radio-dot::after { content: ""; width: 8px; height: 8px; border-radius: var(--r-pill); background: var(--accent); transform: scale(0); transition: transform var(--dur-1) var(--ease-standard); } .cx-radio-input:checked + .cx-check-face .cx-radio-dot { border-color: var(--accent); } .cx-radio-input:checked + .cx-check-face .cx-radio-dot::after { transform: scale(1); } .cx-radio-input:focus-visible + .cx-check-face .cx-radio-dot { border-color: var(--accent); box-shadow: var(--focus-ring); } .cx-select-md { height: var(--ctl-h-lg); padding: 0 var(--ctl-pad-x-md); font-size: var(--fs-4); } .cx-select-sm { height: var(--ctl-h-md); padding: 0 var(--ctl-pad-x-sm); font-size: var(--fs-5); } .cx-segmented { display: inline-flex; border: var(--bw) solid var(--line); border-radius: var(--ctl-r); overflow: hidden; background: var(--elev-2); } .cx-segment { border: 0; background: transparent; color: var(--muted); cursor: pointer; font-family: var(--font-ui); border-left: var(--bw) solid var(--line); transition: background var(--dur-1) var(--ease-standard), color var(--dur-1) var(--ease-standard); } .cx-segment:first-child { border-left: 0; } .cx-segmented-md .cx-segment { height: var(--ctl-h-lg); padding: 0 var(--ctl-pad-x-lg); font-size: var(--fs-5); } .cx-segmented-sm { padding: var(--sp-1); gap: var(--sp-1); } .cx-segmented-sm .cx-segment { height: var(--ctl-h-sm); padding: 0 var(--ctl-pad-x-md); font-size: var(--fs-6); border-left: 0; border-radius: var(--r-2); } .cx-segment:hover { background: var(--hover); color: var(--text); } .cx-segment.cx-on { background: var(--accent-soft); color: var(--accent-hi); } .cx-toggle-track { width: 34px; height: 20px; flex: none; border-radius: var(--r-pill); background: var(--line); position: relative; transition: background var(--dur-1) var(--ease-standard); } .cx-toggle-knob { position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: var(--r-pill); background: var(--elev-1); transition: transform var(--dur-1) var(--ease-standard); } .cx-toggle-input:checked + .cx-check-face .cx-toggle-track { background: var(--accent); } .cx-toggle-input:checked + .cx-check-face .cx-toggle-track .cx-toggle-knob { transform: translateX(14px); } .cx-toggle-input:focus-visible + .cx-check-face .cx-toggle-track { box-shadow: var(--focus-ring); } /* Colour: the swatch sized to the control height so it lines up with every other field in a settings column, and the hex field kept narrow because six characters in a full-width input reads as an empty box. */ .cx-swatch-row { display: flex; align-items: center; gap: var(--sp-4); } .cx-swatch { inline-size: var(--ctl-h-lg); block-size: var(--ctl-h-lg); padding: 0; border: var(--bw) solid var(--line); border-radius: var(--ctl-r); background: var(--elev-1); cursor: pointer; } .cx-swatch::-webkit-color-swatch-wrapper { padding: 2px; } .cx-swatch::-webkit-color-swatch { border: 0; border-radius: var(--r-2); } .cx-swatch::-moz-color-swatch { border: 0; border-radius: var(--r-2); } .cx-swatch:disabled { opacity: var(--disabled-opacity); cursor: default; } .cx-swatch-hex { inline-size: 10ch; font-family: var(--font-mono); }