/*! Latch · (c) 2026 Antichaos — antichaosdata.com. All rights reserved. Proprietary. */
/* The control itself — switch / checkbox / segmented / buttons. Shared by the runtime
   (latch.css shell) and the config dialog's live preview, so both look identical. */
:root {
    --accent: #4f7cf0;   /* ON / active */
    --off: #c7cfda;      /* OFF track */
    --knob: #ffffff;     /* switch knob / checkbox tick */
    --text: #151b26;     /* labels + title */
    --radius: 10px;      /* segmented / button corners */
    --scale: 1;          /* size multiplier (sm/md/lg) */
    --fs: 14px;          /* label font size */
}

.control { max-width: 100%; }

/* Title + control stack (or side-by-side when titlepos = left). */
.latch-layout { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.latch-layout.title-left { flex-direction: row; align-items: center; gap: 12px; }
.control.align-center .latch-layout { align-items: center; }
.control.align-right .latch-layout { align-items: flex-end; }
.control.align-left .latch-layout { align-items: flex-start; }
.latch-title {
    font-size: var(--fs); font-weight: 700; letter-spacing: -.01em; color: var(--text);
    white-space: nowrap;
}

/* ---- Switch ---------------------------------------------------------- */
/* --u is the switch's size unit: the sm/md/lg --scale times the fine --swscale slider. */
.sw-wrap { --u: calc(var(--scale) * var(--swscale, 1)); display: inline-flex; align-items: center; gap: calc(10px * var(--scale)); }
.sw-side {
    font-size: var(--fs); font-weight: 600; color: color-mix(in srgb, var(--text) 45%, transparent);
    white-space: nowrap; transition: color .15s ease;
}
.sw-side.is-active { color: var(--text); }
.sw {
    position: relative; flex: 0 0 auto; border: 0; padding: 0; cursor: pointer; background: none;
    width: calc(48px * var(--u)); height: calc(27px * var(--u));
}
.sw-track {
    position: absolute; inset: 0; border-radius: 999px;
    background: var(--off); transition: background .18s ease;
}
.sw.is-on .sw-track { background: var(--accent); }
.sw-knob {
    position: absolute; top: 50%; left: calc(3px * var(--u));
    width: calc(21px * var(--u)); height: calc(21px * var(--u));
    border-radius: 50%; background: var(--knob);
    transform: translateY(-50%);
    box-shadow: 0 1px 3px rgba(20, 28, 42, .35);
    /* springy travel: a bold overshoot so the toggle really bounces into place */
    transition: left .4s cubic-bezier(.5, 2.1, .5, 1), width .16s ease;
}
.sw.is-on .sw-knob { left: calc(100% - 24px * var(--u)); }
.sw:active .sw-knob { width: calc(29px * var(--u)); }   /* squash toward the press */
.sw:focus-visible { outline: none; }
.sw:focus-visible .sw-track { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 30%, transparent); }

/* SVG switch designs (switch-svgs.js). The designs read --toggle-on/off/knob; map them to
   Latch's colour settings so any style recolours from the same on/off/knob pickers. The SVG's
   own 64x36 aspect is preserved; --scale drives the width. */
.sw--svg {
    --toggle-on: var(--accent);
    --toggle-off: var(--off);
    --toggle-knob: var(--knob);
    width: calc(58px * var(--u)); height: auto;
    background: none; border: 0; padding: 0; line-height: 0;
}
.sw--svg svg { display: block; width: 100%; height: auto; }
.sw--svg:focus-visible { outline: none; border-radius: 999px; box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 30%, transparent); }

/* ---- Checkbox -------------------------------------------------------- */
.cb {
    display: inline-flex; align-items: center; gap: calc(9px * var(--scale));
    border: 0; background: none; padding: 0; cursor: pointer; color: var(--text);
}
.cb-box {
    flex: 0 0 auto;
    width: calc(22px * var(--scale)); height: calc(22px * var(--scale));
    border-radius: calc(var(--radius) * .55); box-sizing: border-box;
    border: 2px solid var(--off); background: #fff;
    display: flex; align-items: center; justify-content: center;
    transition: background .15s ease, border-color .15s ease;
}
.cb.is-on .cb-box { background: var(--accent); border-color: var(--accent); }
/* Box shape (square / rounded / circle) — overrides the default radius above. */
.cb-box.cb-shape-square  { border-radius: calc(var(--radius) * .16); }
.cb-box.cb-shape-rounded { border-radius: calc(var(--radius) * .55); }
.cb-box.cb-shape-circle  { border-radius: 50%; }
/* Mark (check / cross / minus / dot; 'fill' draws no glyph — the filled box is the cue).
   Revealed with a scale/opacity pop so every mark shape animates the same way. */
.cb-box svg {
    width: 72%; height: 72%; color: var(--knob);
    opacity: 0; transform: scale(.4);
    transition: opacity .14s ease, transform .18s cubic-bezier(.3, .7, .4, 1.5);
}
.cb-box svg path { fill: none; stroke: currentColor; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.cb-box svg circle { fill: currentColor; }
.cb.is-on .cb-box svg { opacity: 1; transform: none; }
.cb-label { font-size: var(--fs); font-weight: 600; white-space: nowrap; }
.cb:focus-visible .cb-box { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 30%, transparent); }

/* ---- Segmented / Buttons -------------------------------------------- */
.grp { display: inline-flex; }
.grp-seg {
    border: 1px solid var(--off); border-radius: var(--radius); overflow: hidden;
    background: color-mix(in srgb, var(--off) 22%, #fff);
}
.grp-btn { gap: calc(8px * var(--scale)); flex-wrap: wrap; }

.grp-item {
    border: 0; cursor: pointer; font-family: inherit;
    font-size: var(--fs); font-weight: 650; color: color-mix(in srgb, var(--text) 62%, transparent);
    padding: calc(8px * var(--scale)) calc(15px * var(--scale));
    background: transparent; white-space: nowrap;
    display: inline-flex; align-items: center; justify-content: center; gap: calc(6px * var(--scale));
    transition: background .15s ease, color .15s ease, box-shadow .15s ease;
}
.grp-ico { line-height: 1; font-size: 1.08em; }   /* per-value icon/emoji */
.grp-seg .grp-item + .grp-item { border-left: 1px solid var(--off); }
.grp-seg .grp-item.is-active { background: var(--accent); color: #fff; }
.grp-seg .grp-item:not(.is-active):hover { background: color-mix(in srgb, var(--accent) 10%, transparent); color: var(--text); }

.grp-btn .grp-item {
    border-radius: var(--radius);
    border: 1px solid var(--off); background: #fff;
}
.grp-btn .grp-item.is-active {
    background: var(--accent); color: #fff; border-color: var(--accent);
    box-shadow: 0 2px 8px color-mix(in srgb, var(--accent) 32%, transparent);
}
.grp-btn .grp-item:not(.is-active):hover { border-color: var(--accent); color: var(--text); }
.grp-item:focus-visible { outline: none; box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 30%, transparent); }

/* ---- Segmented design variants (base .grp-seg = "filled") ------------ */
/* Pill: rounded track with a floating rounded active pill (iOS-style). */
.grp-seg.seg-pill { border-radius: 999px; padding: calc(3px * var(--scale)); background: color-mix(in srgb, var(--off) 28%, #fff); }
.grp-seg.seg-pill .grp-item { border-radius: 999px; }
.grp-seg.seg-pill .grp-item + .grp-item { border-left: 0; }
.grp-seg.seg-pill .grp-item.is-active { box-shadow: 0 1px 4px rgba(20, 28, 42, .18); }
/* Underline: text tabs, active marked by an accent underline (no fill). */
.grp-seg.seg-underline { border: 0; border-radius: 0; background: none; overflow: visible; border-bottom: 2px solid color-mix(in srgb, var(--off) 75%, #fff); }
.grp-seg.seg-underline .grp-item { position: relative; background: none; }
.grp-seg.seg-underline .grp-item + .grp-item { border-left: 0; }
.grp-seg.seg-underline .grp-item.is-active { background: none; color: var(--accent); }
.grp-seg.seg-underline .grp-item.is-active::after { content: ''; position: absolute; left: 10%; right: 10%; bottom: -2px; height: 2.5px; border-radius: 2px; background: var(--accent); }
.grp-seg.seg-underline .grp-item:not(.is-active):hover { background: none; color: var(--text); }
/* Outline: transparent track, active is a soft tinted chip with accent text. */
.grp-seg.seg-outline { background: none; border-color: color-mix(in srgb, var(--off) 82%, #fff); }
.grp-seg.seg-outline .grp-item.is-active { background: color-mix(in srgb, var(--accent) 13%, #fff); color: var(--accent); }

/* ---- Button design variants (base .grp-btn = "solid") --------------- */
.grp-btn.btn-outline .grp-item { border-color: var(--accent); color: var(--accent); background: #fff; }
.grp-btn.btn-outline .grp-item.is-active { background: var(--accent); color: #fff; box-shadow: none; }
.grp-btn.btn-soft .grp-item { border-color: transparent; background: color-mix(in srgb, var(--accent) 12%, #fff); color: var(--accent); }
.grp-btn.btn-soft .grp-item:not(.is-active):hover { background: color-mix(in srgb, var(--accent) 20%, #fff); border-color: transparent; }
.grp-btn.btn-soft .grp-item.is-active { background: var(--accent); color: #fff; border-color: var(--accent); box-shadow: 0 2px 8px color-mix(in srgb, var(--accent) 30%, transparent); }
.grp-btn.btn-pill .grp-item { border-radius: 999px; }

/* Vertical orientation (segmented + buttons). Items stack and stretch to equal width. */
.grp.is-vertical { flex-direction: column; align-items: stretch; }
.grp-seg.is-vertical .grp-item + .grp-item { border-left: 0; border-top: 1px solid var(--off); }
.grp.is-vertical .grp-item { text-align: center; }

/* Overflow: a horizontal segmented control never wider than its zone — it scrolls instead of
   spilling. Buttons already wrap. */
.grp-seg:not(.is-vertical) { max-width: 100%; overflow-x: auto; scrollbar-width: thin; }
.grp-seg:not(.is-vertical)::-webkit-scrollbar { height: 5px; }
.grp-seg:not(.is-vertical)::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--off) 80%, #fff); border-radius: 5px; }

/* ---- Checkbox label placement / weight (config_cblabelpos / bold / upper) --- */
.cb-label.is-bold { font-weight: 800; }
.cb-label.is-upper { text-transform: uppercase; letter-spacing: .04em; }
.cb.cb-lbl-hidden { gap: 0; }

/* ---- Slider (range parameter, or slide through a list by index) ------ */
.sld-wrap { display: inline-flex; align-items: center; gap: calc(11px * var(--scale)); width: 100%; max-width: calc(240px * var(--scale)); }
.sld { flex: 1 1 auto; min-width: 54px; accent-color: var(--accent); cursor: pointer; height: calc(var(--fs) * 1.2); }
.sld-val {
    font-size: var(--fs); font-weight: 700; color: var(--text); white-space: nowrap;
    min-width: 2.2em; text-align: right; font-variant-numeric: tabular-nums;
}

/* ---- Stepper (−/+ around the value) --------------------------------- */
.stp-wrap { display: inline-flex; align-items: center; gap: calc(6px * var(--scale)); }
.stp-btn {
    flex: 0 0 auto; border: 1px solid var(--off); background: #fff; color: var(--text); cursor: pointer;
    width: calc(30px * var(--scale)); height: calc(30px * var(--scale)); border-radius: var(--radius);
    font-size: calc(var(--fs) * 1.25); font-weight: 700; line-height: 1;
    display: flex; align-items: center; justify-content: center;
    transition: background .15s ease, border-color .15s ease, color .15s ease, transform .1s ease;
}
.stp-btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.stp-btn:active:not(:disabled) { transform: scale(.9); }
.stp-btn:disabled { opacity: .38; cursor: default; }
.stp-val {
    font-size: var(--fs); font-weight: 700; color: var(--text); white-space: nowrap;
    min-width: 2.6em; text-align: center; font-variant-numeric: tabular-nums; padding: 0 calc(4px * var(--scale));
}

/* ---- interaction animation ------------------------------------------ */
/* One-shot "pop" replayed by latch.js (pulse()) where a slide can't carry the change: an SVG
   switch swapping its whole graphic, and the newly-active segment / button. */
@keyframes latch-pop { 0% { transform: scale(.7); } 45% { transform: scale(1.28); } 72% { transform: scale(.93); } 100% { transform: scale(1); } }
.latch-pulse { animation: latch-pop .42s cubic-bezier(.3, .7, .4, 1.5); transform-origin: center; }
.cb-box { transition: background .15s ease, border-color .15s ease, transform .12s ease; }
/* tactile press: the control gives noticeably under a click/tap */
.cb:active .cb-box { transform: scale(.82); }
.grp-item { transition: background .15s ease, color .15s ease, box-shadow .15s ease, transform .1s ease; }
.grp-item:active { transform: scale(.9); }

/* Animation intensity (config_anim → data-anim on <html>). Default/unset = the pronounced
   "bounce" above. "smooth" is a quick, overshoot-free version; "none" is instant. */
@keyframes latch-pop-soft { 0% { transform: scale(.92); } 60% { transform: scale(1.06); } 100% { transform: scale(1); } }
[data-anim="smooth"] .sw-knob { transition: left .2s ease, width .12s ease; }
[data-anim="smooth"] .sw:active .sw-knob { width: calc(24px * var(--u)); }
[data-anim="smooth"] .latch-pulse { animation: latch-pop-soft .22s ease; }
[data-anim="smooth"] .cb:active .cb-box { transform: scale(.92); }
[data-anim="smooth"] .grp-item:active { transform: scale(.96); }

[data-anim="none"] .sw-track, [data-anim="none"] .sw-knob, [data-anim="none"] .cb-box,
[data-anim="none"] .cb-box svg, [data-anim="none"] .grp-item { transition: none; }
[data-anim="none"] .latch-pulse { animation: none; }
[data-anim="none"] .sw:active .sw-knob { width: calc(21px * var(--u)); }
[data-anim="none"] .cb:active .cb-box, [data-anim="none"] .grp-item:active, [data-anim="none"] .stp-btn:active { transform: none; }

/* Users who ask the OS for less motion always get the instant version, whatever the setting. */
@media (prefers-reduced-motion: reduce) {
    .sw-track, .sw-knob, .cb-box, .cb-box svg, .grp-item { transition: none; }
    .latch-pulse { animation: none; }
    .sw:active .sw-knob { width: calc(21px * var(--u)); }   /* no squash */
    .cb:active .cb-box, .grp-item:active, .stp-btn:active { transform: none; }   /* no press-scale */
    .stp-btn { transition: none; }
}

/* ---- label alignment inside segmented / buttons (esp. vertical, menu-like) ---- */
.grp.lbl-left  .grp-item { justify-content: flex-start; text-align: left; }
.grp.lbl-right .grp-item { justify-content: flex-end;   text-align: right; }
.grp.lbl-center .grp-item { justify-content: center;    text-align: center; }
/* let the label take the row so alignment is visible on full-width vertical items */
.grp.is-vertical .grp-lbl { flex: 1 1 auto; }
