/* ═══════════════════════════════════════════════════════════════════════════
   STARKIT: the family control kit.

   BASE ONLY. This file is the CONTROLS, meaning geometry, states and behaviour.
   It contains no hardcoded token of any kind: no hex, no font stack, no radius
   (operator ruling 2026-07-26, "no hardcoded tokens in starkit. starkit is fully
   themable"). Every value below is a var(--star-*) that a theme file supplies.

   VOCABULARY. --star-* , the NAMESPACE starstyle owns. The kit used to speak
   --sk-* , which meant one design system with two dialects and no theme could
   cross between them. Collapsed to --star-* on operator ruling 2026-07-26.

   NOT ALL OF THEM ARE CANON, AND THIS FILE USED TO CLAIM THEY WERE. The header
   said "the same names starstyle emits from themeToCss()". Measured 2026-07-31:
   63 --star-* names live in this kit and 39 of them are ABSENT from starstyle's
   134-token contract. They are kit-local extensions wearing the canon prefix,
   which is worse than a private prefix would have been: a reader takes the name
   as contract-backed, and a theme generated from starstyle supplies nothing for
   it, so the var() falls through to whatever literal happens to be there.

   The 39 are not renamed here. That is a migration across 22 pages and it needs
   an operator ruling, because renaming a token consumers already write is a
   breaking change to a surface every agent-built page loads. What IS enforced is
   that the number can only fall: tests/token-canon.test.mjs holds it as a
   shrink-only ratchet, so a new non-canon name is refused and a genuine
   migration is recorded as progress.

   RADIUS IS A TOKEN, NOT A LAW. It was `*{border-radius:0!important}` here, which
   made "fully themable" and the 2026-07-23 zero-radius ruling contradictory: a
   rounded theme could not exist. Zero radius is now what PIXELFLAME sets, not what
   starkit enforces. Themes with a radius scale (ledger-light: 22px panel down to
   7px badge) are first-class. Roles, not pixels: panel / card / tile / control /
   badge / pill.

   The one exception is a MARK. A diamond is a perfect square rotated 45 degrees
   (CANON L1); give it a radius and it stops being one, which is why FEN-026
   refuses a rounded diamond cell in any theme. Marks are hardcoded to 0 and say so
   inline. A theme wanting round knobs opts into [data-shape="square"] first, where
   --star-radius-mark applies.

   IMPORT BOTH, base first. Never copy or re-create either per page:
     <link rel="stylesheet" href="/brands/visual-language/starkit/starkit.css">
     <link rel="stylesheet" href="/brands/visual-language/starkit/theme-pixelflame.css">
   Swap the second file to re-skin: theme-ledger-light.css, or any starstyle preset.
   ═══════════════════════════════════════════════════════════════════════════ */
/* Nothing below names a colour, a font, or a radius directly. Every value is a
   var(--star-*), supplied by whichever theme file the page imports. That is the
   whole point: no hardcoded tokens in starkit (operator ruling 2026-07-26). */

/* ── Base field furniture ─────────────────────────────────────────────────── */
.sk-field { margin: 0 0 17px; }
.sk-field > label, .sk-legend {
  display: flex;
  justify-content: space-between;
  margin: 0 0 7px;
  color: var(--star-ink-muted);
  font: 600 10px/1.2 var(--star-font-mono);
  letter-spacing: .09em;
  text-transform: uppercase;
}
.sk-field output { color: var(--star-accent); }

/* ── Select ───────────────────────────────────────────────────────────────── */
.sk-select {
  appearance: none;
  width: 100%;
  min-height: 38px;
  padding: 9px 13px 9px 11px;
  border: 1px solid var(--star-border);
  border-radius: var(--star-radius-control);
  color: var(--star-ink-title);
  background:
    linear-gradient(45deg, transparent 49%, var(--star-accent) 50%) calc(100% - 14px) 55% / 7px 7px no-repeat,
    linear-gradient(-45deg, transparent 49%, var(--star-accent) 50%) calc(100% - 7px) 55% / 7px 7px no-repeat,
    var(--star-surface);
  font: 500 13px/1.35 var(--star-font-mono);
  cursor: pointer;
}
.sk-select:focus-visible { outline: 2px solid var(--star-info); outline-offset: 2px; }
/* open dropdown list: customizable select (Chromium 135+) + option fallback */
@supports (appearance: base-select) {
  .sk-select, .sk-select::picker(select) { appearance: base-select; }
  .sk-select { background: var(--star-surface); }
  .sk-select::picker(select) {
    border: 1px solid var(--star-border);
    border-radius: var(--star-radius-control);
    background: var(--star-surface);
    padding: 4px;
  }
}
.sk-select option {
  padding: 9px 11px;
  border-radius: var(--star-radius-control);
  color: var(--star-ink-title);
  background: var(--star-surface);
  font: 500 13px/1.35 var(--star-font-mono);
}
.sk-select option:hover, .sk-select option:focus { background: var(--star-accent); color: var(--star-bg); }
/* checked row: never signal-on-signal (invisible-text bug 2026-07-23).
   Solid signal bar with ground text, hovered or not. */
.sk-select option:checked { background: var(--star-accent); color: var(--star-bg); }
@supports (appearance: base-select) {
  .sk-select option:checked::checkmark { content: "◆ "; color: var(--star-accent); }
}

/* ── Range slider: square track, DIAMOND thumb (borderless per ruling).
   The filled-track needs --star-fill kept in sync with value: include starkit.js
   (same dir) once per page, and it wires every .sk-range automatically.       */
.sk-range {
  appearance: none;
  width: 100%;
  height: 26px;
  margin: 0;
  background: transparent;
  cursor: pointer;
}
.sk-range::-webkit-slider-runnable-track {
  height: 4px;
  background: linear-gradient(90deg, var(--star-accent) var(--star-fill, 50%), var(--star-border) var(--star-fill, 50%));
}
.sk-range::-moz-range-track { height: 4px; background: var(--star-border); }
.sk-range::-moz-range-progress { height: 4px; background: var(--star-accent); }
.sk-range::-webkit-slider-thumb {
  appearance: none;
  width: 15px;
  height: 15px;
  margin-top: -5.5px;
  background: var(--star-accent);
  border: none;
  border-radius: 0;                /* a mark's radius is geometry, not theme: see header */
  transform: rotate(45deg);        /* the diamond IS the square, rotated (L1) */
  transition: transform 120ms cubic-bezier(0.22, 0.61, 0.36, 1);
}
.sk-range::-moz-range-thumb {
  width: 15px;
  height: 15px;
  background: var(--star-accent);
  border: none;
  border-radius: 0;                /* as above: the diamond must stay a rotated square */
  transform: rotate(45deg);
}
.sk-range:active::-webkit-slider-thumb { transform: rotate(45deg) scale(1.18); }
.sk-range:focus-visible { outline: 2px solid var(--star-info); outline-offset: 4px; }
[data-shape="square"] .sk-range::-webkit-slider-thumb { transform: none; border-radius: var(--star-radius-mark, 0); }
[data-shape="square"] .sk-range:active::-webkit-slider-thumb { transform: scale(1.18); }
[data-shape="square"] .sk-range::-moz-range-thumb { transform: none; border-radius: var(--star-radius-mark, 0); }
[data-shape="square"] .sk-diamond { transform: none; }

/* ── Shape sets (operator, 2026-07-23: "make the borders on the side of the
   diamond be angled like the diamond… and make a version set with square
   instead of diamonds") ───────────────────────────────────────────────────────
   DEFAULT set = diamonds: containers take diamond-parallel 45° edges (chamfered
   checkbox, pointed switch rail), marks/knobs/thumbs are diamonds.
   [data-shape="square"] set: straight containers, square marks/knobs/thumbs.  */

/* ── Checkbox: chamfered box (edges parallel to the diamond), diamond mark ─── */
.sk-check {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--star-ink-title);
  font: 500 12px/1.4 var(--star-font-mono);
  cursor: pointer;
}
.sk-check input {
  /* a plain square FRAME so it reads as a checkbox (operator 2026-07-23);
     the mark inside stays the borderless diamond (LAW) */
  appearance: none;
  width: 18px;
  height: 18px;
  margin: 0;
  border: 1px solid var(--star-border);
  border-radius: var(--star-radius-badge);
  background: var(--star-surface);
  display: grid;
  place-items: center;
  cursor: pointer;
  flex: none;
  transition: border-color 130ms;
}
.sk-check input::before {
  content: "";
  width: 9px;
  height: 9px;
  background: var(--star-accent);
  transform: rotate(45deg) scale(0);
  transition: transform 140ms cubic-bezier(0.22, 0.61, 0.36, 1);
}
.sk-check input:checked::before { transform: rotate(45deg) scale(1); }
.sk-check input:checked { border-color: var(--star-accent); }
.sk-check input:focus-visible { outline: 2px solid var(--star-info); outline-offset: 2px; }
[data-shape="square"] .sk-check input::before { transform: scale(0); }
[data-shape="square"] .sk-check input:checked::before { transform: scale(1); }

/* ── Switch: square rail, diamond knob ────────────────────────────────────── */
.sk-switch {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--star-ink-title);
  font: 500 12px/1.4 var(--star-font-mono);
  cursor: pointer;
}
.sk-switch input {
  appearance: none;
  width: 34px;
  height: 15px;
  margin: 0;
  border: none;
  border-radius: var(--star-radius-pill);
  background: linear-gradient(var(--star-border), var(--star-border)) 50% 50% / calc(100% - 6px) 2px no-repeat;
  position: relative;
  cursor: pointer;
  flex: none;
}
.sk-switch input::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  width: 10px;
  height: 10px;
  background: var(--star-ink-muted);
  transform: translateY(-50%) rotate(45deg);
  transition: left 160ms cubic-bezier(0.22, 0.61, 0.36, 1), background 160ms;
}
.sk-switch input:checked {
  background: linear-gradient(var(--star-accent), var(--star-accent)) 50% 50% / calc(100% - 6px) 2px no-repeat;
}
.sk-switch input:checked::after { left: 24px; background: var(--star-accent); }
.sk-switch input:focus-visible { outline: 2px solid var(--star-info); outline-offset: 3px; }
[data-shape="square"] .sk-switch input::after { transform: translateY(-50%); }

/* ── File input: the "Choose File" default is dead ────────────────────────── */
.sk-file {
  width: 100%;
  color: var(--star-ink-muted);
  font: 500 11px/1.4 var(--star-font-mono);
}
.sk-file::file-selector-button {
  margin-right: 12px;
  padding: 9px 14px;
  border: 1px solid var(--star-accent);
  border-radius: var(--star-radius-control);
  color: var(--star-accent);
  background: transparent;
  font: 600 10px/1 var(--star-font-mono);
  letter-spacing: .08em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 140ms, color 140ms;
}
.sk-file::file-selector-button:hover { background: var(--star-accent); color: var(--star-bg); }

/* ── Buttons ──────────────────────────────────────────────────────────────── */
.sk-btn {
  min-height: 38px;
  padding: 9px 16px;
  border: 1px solid var(--star-border);
  border-radius: var(--star-radius-control);
  color: var(--star-ink-title);
  background: transparent;
  font: 600 10px/1 var(--star-font-mono);
  letter-spacing: .08em;
  text-transform: uppercase;
  cursor: pointer;
}
.sk-btn.primary { border-color: var(--star-accent); background: var(--star-accent); color: var(--star-bg); }
.sk-btn.quiet:hover, .sk-btn:not(.primary):hover { border-color: var(--star-accent-hi); }
.sk-btn:focus-visible { outline: 2px solid var(--star-info); outline-offset: 2px; }

/* ── Color input ──────────────────────────────────────────────────────────── */
.sk-color {
  appearance: none;
  width: 100%;
  height: 30px;
  padding: 3px;
  border: 1px solid var(--star-border);
  border-radius: var(--star-radius-control);
  background: var(--star-surface);
  cursor: pointer;
  box-sizing: border-box;
}
.sk-color::-webkit-color-swatch-wrapper { padding: 0; }
.sk-color::-webkit-color-swatch { border: none; border-radius: var(--star-radius-control); }
.sk-color::-moz-color-swatch { border: none; border-radius: var(--star-radius-control); }

/* ── Diamond glyph, LAW (operator, 2026-07-23): "no, kill it. no border as law."
   A diamond glyph is ALWAYS borderless. (The glow-ring experiment is dead.)      */
.sk-diamond {
  display: inline-block;
  width: 10px;
  height: 10px;
  background: var(--star-accent);
  border: none;
  transform: rotate(45deg);
  vertical-align: -1px;
}

/* ── Segmented group ──────────────────────────────────────────────────────── */
.sk-segmented { display: grid; grid-auto-flow: column; border: 1px solid var(--star-border); }
.sk-segmented button {
  min-height: 34px;
  padding: 5px 10px;
  color: var(--star-ink-muted);
  border: 0;
  border-right: 1px solid var(--star-border);
  border-radius: var(--star-radius-control);
  background: transparent;
  font: 600 10px/1 var(--star-font-mono);
  cursor: pointer;
}
.sk-segmented button:last-child { border-right: 0; }
.sk-segmented button[aria-pressed="true"] { color: var(--star-bg); background: var(--star-ink-title); }

/* ── Face toggle, light to dark (operator ruling 2026-07-24: "always make them
   both light mode / dark mode with toggle"). The ONE canonical light/dark control;
   every agent-built HTML surface includes it. Pairs with starkit.js (auto-wires
   [data-face], persists to localStorage, honors prefers-color-scheme on first load). */
.sk-face-toggle {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 34px;
  padding: 7px 13px;
  border: 1px solid var(--star-border);
  border-radius: var(--star-radius-control);
  color: var(--star-ink-title);
  background: transparent;
  font: 600 10px/1 var(--star-font-mono);
  letter-spacing: .08em;
  text-transform: uppercase;
  cursor: pointer;
  transition: border-color 140ms, color 140ms;
}
.sk-face-toggle:hover { border-color: var(--star-accent-hi); color: var(--star-accent); }
.sk-face-toggle:focus-visible { outline: 2px solid var(--star-info); outline-offset: 2px; }
.sk-face-toggle i { font-size: 15px; color: var(--star-accent); }
/* show the icon/label for the face you'd switch TO (dark face → offer "light", and vice-versa) */
.sk-face-toggle .sk-face-to-light,
[data-face="light"] .sk-face-toggle .sk-face-to-dark { display: inline-flex; align-items: center; gap: 7px; }
.sk-face-toggle .sk-face-to-dark,
[data-face="light"] .sk-face-toggle .sk-face-to-light { display: none; }
/* Positioned variant. A surface with its own header puts the toggle in it; a surface
   without one (poster sheets, contact sheets, one-page landings) uses this and gets the
   control without 11 pages each inventing their own placement CSS. */
.sk-face-toggle.sk-face-fixed {
  position: fixed;
  top: 14px;
  right: 14px;
  z-index: 9999;
  background: var(--star-bg);
}

/* ---------------------------------------------------------------------------
   Reduced motion. The kit had NO prefers-reduced-motion rule in any of its five
   files while carrying six transitions, so every page that loads it, which root
   AGENTS.md makes every page an agent creates, ignored the setting entirely.

   This kills the TRAVEL and keeps the STATE. Every rule above animates a
   property whose settled value is the meaningful one (transform on a press,
   left on a toggle thumb, border-color and background on hover), so arriving
   there instantly loses nothing. That is the doctrine's line: reduced motion
   changes behaviour, it never hides information. It is expressed as a near-zero
   duration rather than `transition: none` so a transitionend listener still
   fires and no JS that waits on one can hang.
   --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .sk-check,
  .sk-file,
  .sk-range,
  .sk-switch,
  .sk-switch::after,
  .sk-face-toggle {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}
