/* CLAUDE 10-18 (design polish B1, analysis/DESIGN-POLISH-PLAN-2026-10-18.md section 4.4): the control primitives.
   Built once, adopted by every later batch (each surface deletes its own copy). The tab, chip and row values are the ones
   the owner's 10-18 "tacky menus" fix settled on in phonescreen.css / autocaps.css (quiet text tabs, light capsule
   chips, plain rows with a hairline), lifted here so a desktop panel and a phone sheet read the same.
   Graphite: no box unless it carries meaning, green only for state, one primary per area. Loaded after motion.css. */

/* ===== .m-tabs: plain text on one hairline, a straight 2 px bar that slides under the open tab ===== */
.m-tabs {
  position: relative;
  display: flex;
  align-items: stretch;
  gap: 0;
  border-bottom: 1px solid var(--c-line);
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
}
.m-tabs::-webkit-scrollbar {
  display: none;
}
.m-tabs > :is(button, a, [role='tab']) {
  position: relative;
  flex: none;
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 0 var(--s-3);
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--c-fg-3);
  font-size: var(--t-label);
  font-weight: 500;
  white-space: nowrap;
  text-decoration: none;
}
.m-tabs > :is(.active, [aria-selected='true'], [aria-current='page'], [aria-current='true']) {
  color: var(--c-fg);
  background: transparent;
}
@media (hover: hover) and (pointer: fine) {
  .m-tabs > :is(button, a, [role='tab']):hover {
    color: var(--c-fg);
    background: transparent;
  }
}
.m-tabs > :is(button, a, [role='tab']):focus-visible {
  outline: 2px solid var(--c-focus);
  outline-offset: -4px;
  border-radius: var(--r-sm);
}
/* the bar: one element on the container, moved by --tab-x / --tab-w from motion.js (never an inset shadow, never rounded) */
.m-tabs.m-js::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 1px;
  height: 2px;
  background: var(--c-fg);
  transform-origin: 0 0;
  transform: translateX(var(--tab-x, 0px)) scaleX(var(--tab-w, 1));
  opacity: var(--tab-on, 0);
  transition:
    transform 240ms var(--ease-out),
    opacity var(--d-hover) ease;
  pointer-events: none;
}
/* without the script the open tab still shows a straight bar */
.m-tabs:not(.m-js) > :is(.active, [aria-selected='true'], [aria-current='page'])::after {
  content: '';
  position: absolute;
  inset: auto var(--s-3) 0;
  height: 2px;
  background: var(--c-fg);
}
/* a scrolling row fades out at its edge instead of being cut */
.m-tabs.m-fade-x {
  padding-right: 24px;
  -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 24px), transparent);
  mask-image: linear-gradient(90deg, #000 calc(100% - 24px), transparent);
}
@media (pointer: coarse) {
  .m-tabs > :is(button, a, [role='tab']) {
    min-height: var(--h-touch);
    font-size: 14px;
    font-weight: 550;
  }
}

/* ===== .m-seg: one subtle track with a sliding thumb, for 2 to 4 exclusive options ===== */
.m-seg {
  position: relative;
  display: inline-flex;
  padding: 2px;
  background: var(--c-raised);
  border-radius: var(--r-sm);
}
.m-seg > :is(button, label, [role='radio'], [role='tab']) {
  position: relative;
  z-index: 1;
  flex: 1 1 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 56px;
  min-height: calc(var(--h-md) - 4px);
  padding: 0 var(--s-3);
  border: 0;
  border-radius: var(--r-xs);
  background: transparent;
  color: var(--c-fg-2);
  font-size: var(--t-label);
  font-weight: 500;
  white-space: nowrap;
}
.m-seg > :is(.active, [aria-selected='true'], [aria-checked='true'], [aria-pressed='true']) {
  color: var(--c-fg);
  background: transparent;
}
/* the thumb slides (tabs() with inset 0 gives it x and width); without the script the open one carries it itself */
.m-seg.m-js::before {
  content: '';
  position: absolute;
  top: 2px;
  bottom: 2px;
  left: 0;
  width: calc(var(--tab-w, 0) * 1px);
  border-radius: var(--r-xs);
  background: var(--c-overlay);
  box-shadow: var(--hl);
  transform: translateX(var(--tab-x, 0px));
  opacity: var(--tab-on, 0);
  transition: transform 240ms var(--ease-out);
}
.m-seg:not(.m-js) > :is(.active, [aria-selected='true'], [aria-checked='true'], [aria-pressed='true']) {
  background: var(--c-overlay);
  box-shadow: var(--hl);
}
.m-seg > :focus-visible {
  outline: 2px solid var(--c-focus);
  outline-offset: 0;
}

/* ===== .m-chip: a light capsule; the open one on a soft fill, never an outlined pill ===== */
.m-chip {
  position: relative;
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  min-height: var(--h-sm);
  padding: 0 var(--s-3);
  border: 0;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--c-fg-2);
  font-size: var(--t-label);
  font-weight: 500;
  white-space: nowrap;
  text-decoration: none;
  scroll-snap-align: start;
}
.m-chip:is(.active, .selected, [aria-selected='true'], [aria-pressed='true'], [aria-checked='true']) {
  background: rgba(242, 240, 235, 0.1);
  color: var(--c-fg);
}
@media (hover: hover) and (pointer: fine) {
  .m-chip:hover {
    background: var(--c-raised);
    color: var(--c-fg);
  }
  .m-chip:is(.active, .selected, [aria-selected='true'], [aria-pressed='true'], [aria-checked='true']):hover {
    background: rgba(242, 240, 235, 0.14);
  }
}
.m-chip:focus-visible {
  outline: 2px solid var(--c-focus);
  outline-offset: 0;
}
@media (pointer: coarse) {
  .m-chip {
    min-height: 30px;
  }
  .m-chip::after {
    content: ''; /* 30 px to the eye, 44 px to the finger */
    position: absolute;
    inset: -7px -1px;
  }
}

/* ===== .m-row: the setting row, the name at the left and the choice at the right, a hairline under it, no box ===== */
.m-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  width: 100%;
  min-height: 36px;
  padding: 0;
  border: 0;
  border-bottom: 1px solid var(--c-line);
  border-radius: 0;
  background: transparent;
  color: var(--c-fg);
  font-size: var(--t-body);
  text-align: left;
}
.m-row :is(select, input) {
  width: auto;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background-color: transparent;
  color: var(--c-fg-2);
  text-align: right;
}
.m-row:focus-visible,
.m-row:focus-within {
  outline: 2px solid var(--c-focus);
  outline-offset: -2px;
  border-radius: var(--r-sm);
}
@media (pointer: coarse) {
  .m-row {
    min-height: var(--h-touch);
  }
}

/* ===== .m-field: input and select. A label above, an error below ===== */
.m-label {
  display: block;
  margin-bottom: var(--s-2);
  color: var(--c-fg-2);
  font-size: var(--t-label);
  font-weight: 500;
}
.m-field {
  width: 100%;
  min-height: var(--h-md);
  padding: 0 var(--s-3);
  border: 1px solid transparent;
  border-radius: var(--r-field);
  background-color: var(--c-raised);
  box-shadow: none;
  color: var(--c-fg);
  font-size: var(--t-body);
}
.m-field::placeholder {
  color: var(--c-fg-3);
}
.m-field:focus {
  border-color: var(--c-line-strong);
  box-shadow: var(--e-1);
}
.m-field[aria-invalid='true'] {
  border-color: var(--c-danger);
}
.m-err {
  margin-top: var(--s-1);
  color: var(--c-danger);
  font-size: var(--t-label);
}

/* ===== .m-btn: primary / quiet / text / icon ===== */
.m-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  min-height: var(--h-md);
  padding: 0 var(--s-4);
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  background: var(--c-raised);
  color: var(--c-fg);
  font-size: var(--t-body);
  font-weight: 500;
  white-space: nowrap;
  text-decoration: none;
}
.m-btn.primary {
  background: linear-gradient(180deg, #f6f4ef, #ebe8e1);
  color: var(--c-primary-ink);
}
.m-btn.lg {
  min-height: var(--h-lg);
}
.m-btn.text {
  background: transparent;
  color: var(--c-fg-2);
  padding: 0 var(--s-2);
}
.m-btn.icon {
  width: var(--h-sm);
  min-height: var(--h-sm);
  padding: 0;
  background: transparent;
  color: var(--c-fg-2);
}
@media (hover: hover) and (pointer: fine) {
  .m-btn:not(.primary):hover {
    background: var(--c-overlay);
    color: var(--c-fg);
  }
  .m-btn.text:hover,
  .m-btn.icon:hover {
    background: var(--c-raised);
  }
}
@media (pointer: coarse) {
  .m-btn {
    min-height: var(--h-touch);
  }
  .m-btn.icon::after {
    content: '';
    position: absolute;
    inset: -8px; /* 28 px to the eye, 44 px to the finger, without padding */
  }
}
/* loading: the width is held (the label stays, invisible) and a spinner sits in the middle */
.m-btn[aria-busy='true'] {
  color: transparent;
  pointer-events: none;
}
.m-btn[aria-busy='true']::after {
  content: '';
  position: absolute;
  inset: 50% auto auto 50%;
  width: 14px;
  height: 14px;
  margin: -7px 0 0 -7px;
  border: 2px solid var(--c-fg-2);
  border-right-color: transparent;
  border-radius: 50%;
  animation: m-spin 0.7s linear infinite;
}
.m-btn.primary[aria-busy='true']::after {
  border-color: var(--c-primary-ink);
  border-right-color: transparent;
}

/* ===== .m-switch: <label class="m-switch"><input type="checkbox" /><i></i></label>, the Graphite toggle ===== */
.m-switch {
  position: relative;
  display: inline-block;
  flex: none;
  width: 28px;
  height: 16px;
}
.m-switch > input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.m-switch > i {
  position: absolute;
  inset: 0;
  border-radius: var(--r-pill);
  background: var(--c-overlay);
  transition: background-color var(--d-hover) ease;
  pointer-events: none;
}
.m-switch > i::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--c-fg);
  transition: translate 220ms var(--ease-spring);
}
.m-switch > input:checked + i {
  background: var(--c-signal); /* green means on */
}
.m-switch > input:checked + i::after {
  translate: 12px 0;
  background: var(--c-canvas);
}
.m-switch > input:focus-visible + i {
  outline: 2px solid var(--c-focus);
  outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  .m-switch > i::after {
    transition: none; /* the knob jumps, the colour still fades */
  }
}

/* ===== .m-menu items (the surface and its enter / exit are in motion.css) ===== */
.m-menu {
  padding: var(--s-1);
}
.m-menu > :is(button, a, [role='menuitem']) {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  width: 100%;
  min-height: var(--h-md);
  padding: 0 10px;
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--c-fg);
  font-size: var(--t-body);
  text-align: left;
  text-decoration: none;
}
@media (hover: hover) and (pointer: fine) {
  .m-menu > :is(button, a, [role='menuitem']):hover {
    background: var(--c-raised);
  }
}

/* ===== .m-empty: a quiet 20 px icon, one 13 px line, one action; never a paragraph ===== */
.m-empty {
  display: grid;
  justify-items: center;
  gap: var(--s-2);
  padding: var(--s-6) var(--s-4);
  color: var(--c-fg-3);
  font-size: var(--t-body);
  text-align: center;
}
.m-empty > svg {
  width: 20px;
  height: 20px;
  color: var(--c-fg-3);
}
.m-empty > :is(button, a) {
  margin-top: var(--s-1);
}

/* ===== .pin-set: the picked item's setting (duration, length, speed) pinned above a library grid that grows ===== */
/* CLAUDE 10-20 (owner: "the animations should have a slider for how long you want it ... at the top"): it sits in the
   flow just above the grid, so it never covers the first row, and sticks to the top of the sheet's scroller while the
   grid scrolls under it. --pin-top is the height of anything already stuck there (the phone sheet's own header). */
.pin-set {
  position: sticky;
  top: var(--pin-top, 0px);
  z-index: 3;
  margin: 0;
  padding-block: var(--s-2);
  background: var(--pin-bg, var(--c-surface));
}
/* a pinned slider is one line (name, slider, value), so the pinned part stays short and the grid keeps the sheet */
.pin-set .range-field {
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  column-gap: var(--s-3);
  row-gap: 0;
  margin: 0;
}
.pin-set .range-field > input[type='range'] {
  grid-column: 2;
  grid-row: 1;
}
.pin-set .range-field > output {
  grid-column: 3;
  grid-row: 1;
  min-width: 5ch;
  text-align: right;
}
.pin-set :is(input[type='range'], input[type='number'], button):disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
/* CLAUDE 10-21: a transition's Length and Strength pinned together: the names one width, so the two tracks line up,
   and a row's gap between them (a thumb each, not two thumbs touching) */
.cc-cut-pin .range-field {
  grid-template-columns: 4.5em minmax(0, 1fr) auto;
}
.cc-cut-pin .range-field + .range-field {
  margin-top: var(--s-2);
}

/* ===== the editor's setting rows (CLAUDE 11-09, owner: "the physical look of the editor just isn't there") =====
   Every setting in the editor's panels (the Style studio, the left panels, a layer's card, a phone sheet) is one line, as
   the clip Transform's .ci-row (clipinsp.css): its name on the left in a column that lines up down the panel, its control
   on the right. They were the 09-xx stacked forms: an 11 px label over a bare hairline field, a value floating over its
   slider, browser checkboxes and colour wells, pairs of stacked labels side by side. The scope is in :where() so these
   weigh one class: a component's own layout (.dl-card .field, .pin-set .range-field ...) still wins. */
:where(aside.inspector, .cc-content) :is(.field, .range-field, .color-field, .switch-row) {
  --row-name: 38%;
  min-height: 32px;
  margin: 0 0 var(--s-1);
  color: var(--c-fg-2);
  font-size: var(--t-label);
  letter-spacing: 0;
}
/* a name and a menu or a text field */
:where(aside.inspector, .cc-content) .field {
  display: grid;
  grid-template-columns: var(--row-name) minmax(0, 1fr);
  align-items: center;
  column-gap: var(--s-3);
}
/* a name and a number: the number is a small raised field at the row's end (.ci-num's look) */
:where(aside.inspector, .cc-content) .field:has(> input[type='number']) {
  grid-template-columns: minmax(0, 1fr) 68px;
}
/* what cannot be one line stays stacked: a text box, the font picker */
:where(aside.inspector, .cc-content) :is(.field:has(> textarea), .field.font-field) {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--s-2);
}
:where(aside.inspector, .cc-content) .field > :is(select, input:not([type='checkbox'], [type='radio'])) {
  min-width: 0;
  min-height: 32px;
}
:where(aside.inspector, .cc-content) :is(.field, .triple) > input[type='number'] {
  width: 100%;
  height: 28px;
  min-height: 28px;
  padding: 0 8px;
  border: 0;
  border-radius: var(--r-xs);
  background: var(--c-raised);
  color: var(--c-fg);
  font-size: var(--t-label);
  text-align: right;
  font-variant-numeric: tabular-nums;
  appearance: textfield;
  -moz-appearance: textfield;
  transition: box-shadow var(--d-hover) ease;
}
:where(aside.inspector, .cc-content) :is(.field, .triple) > input[type='number']:hover {
  box-shadow: inset 0 0 0 1px var(--c-line-strong);
}
:where(aside.inspector, .cc-content) :is(.field, .triple) > input[type='number']:focus {
  outline: 0;
  box-shadow: inset 0 0 0 1px var(--c-focus);
}
:where(aside.inspector, .cc-content) :is(.field, .triple) > input[type='number']::-webkit-inner-spin-button,
:where(aside.inspector, .cc-content) :is(.field, .triple) > input[type='number']::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
/* a name, the slider and its value on one line (the label's text is an anonymous grid item: it takes column 1) */
:where(aside.inspector, .cc-content) .range-field {
  display: grid;
  grid-template-columns: var(--row-name) minmax(0, 1fr) 44px;
  align-items: center;
  column-gap: var(--s-3);
}
:where(aside.inspector, .cc-content) .range-field > input[type='range'] {
  grid-area: 1 / 2;
  width: 100%;
  margin: 0;
}
:where(aside.inspector, .cc-content) .range-field > output {
  grid-area: 1 / 3;
  color: var(--c-fg);
  font-size: var(--t-label);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
/* a name and its switch / colour at the row's end */
:where(aside.inspector, .cc-content) :is(.color-field, .switch-row) {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
}
/* two or three settings that were set side by side are rows like the rest (a pair of buttons stays a pair) */
:where(aside.inspector, .cc-content) .pair:has(> :is(.field, .range-field, .color-field, .switch-row)) {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
}
/* shadow x / y / blur: three small numbers on one line, each with its letter */
:where(aside.inspector, .cc-content) .triple {
  gap: var(--s-2);
  margin-bottom: var(--s-1);
}
:where(aside.inspector, .cc-content) .triple > .field {
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: 6px;
  margin: 0;
}
:where(aside.inspector, .cc-content) .divider {
  margin: var(--s-2) 0 var(--s-3);
  background: var(--c-line);
}
/* UPPERCASE / Italic / Underline: chips that light up when on (the checkbox is the chip's state, hidden) */
:where(aside.inspector, .cc-content) .toggles {
  gap: 4px;
  margin: 0 0 var(--s-2);
}
:where(aside.inspector, .cc-content) .toggles label {
  position: relative;
  min-height: 28px;
  padding: 0 12px;
  border-radius: var(--r-pill);
  background: var(--c-raised);
  color: var(--c-fg-2);
  font-size: var(--t-label);
  cursor: pointer;
  transition:
    background-color var(--d-hover) ease,
    color var(--d-hover) ease,
    box-shadow var(--d-hover) ease;
}
:where(aside.inspector, .cc-content) .toggles input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
:where(aside.inspector, .cc-content) .toggles label:has(input:checked) {
  background: var(--c-overlay);
  color: var(--c-fg);
  box-shadow: inset 0 0 0 1px var(--c-fg-3);
}
:where(aside.inspector, .cc-content) .toggles label:has(input:focus-visible) {
  outline: 2px solid var(--c-focus);
  outline-offset: 2px;
}

/* ===== every .switch-row's checkbox is the Graphite toggle (.m-switch's look, drawn without its <i>: the knob is a
   gradient, so it needs no pseudo-element on an <input>, which Firefox does not draw) ===== */
.switch-row > input[type='checkbox'] {
  appearance: none;
  -webkit-appearance: none;
  flex: none;
  width: 28px;
  height: 16px;
  margin: 0;
  border-radius: var(--r-pill);
  background:
    radial-gradient(circle closest-side, var(--c-fg) 92%, transparent 100%) no-repeat 2px 50% / 12px 12px,
    var(--c-overlay);
  cursor: pointer;
  transition:
    background-color var(--d-hover) ease,
    background-position 220ms var(--ease-spring);
}
.switch-row > input[type='checkbox']:checked {
  background:
    radial-gradient(circle closest-side, var(--c-canvas) 92%, transparent 100%) no-repeat calc(100% - 2px) 50% / 12px
      12px,
    var(--c-signal); /* green means on */
}
.switch-row > input[type='checkbox']:focus-visible {
  outline: 2px solid var(--c-focus);
  outline-offset: 2px;
}
.switch-row > input[type='checkbox']:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
@media (prefers-reduced-motion: reduce) {
  .switch-row > input[type='checkbox'] {
    transition: background-color var(--d-hover) ease;
  }
}
/* a colour is a soft square swatch, not the browser's grey well */
input[type='color'] {
  appearance: none;
  -webkit-appearance: none;
  flex: none;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  border-radius: var(--r-xs);
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--c-line-strong);
  cursor: pointer;
}
input[type='color']::-webkit-color-swatch-wrapper {
  padding: 0;
}
input[type='color']::-webkit-color-swatch {
  border: 0;
  border-radius: var(--r-xs);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.12);
}
input[type='color']::-moz-color-swatch {
  border: 0;
  border-radius: var(--r-xs);
}

/* a phone's sheet: rows a finger tall, fields 16 px (under 16 px iOS zooms the page on focus) */
@media (max-width: 767.98px) {
  body.pe-on :where(aside.inspector, .cc-content) :is(.field, .range-field, .color-field, .switch-row) {
    min-height: var(--h-touch);
    margin: 0;
  }
  body.pe-on :where(aside.inspector, .cc-content) .range-field > input[type='range'] {
    height: var(--h-touch);
  }
  body.pe-on
    :where(aside.inspector, .cc-content)
    :is(.field, .triple)
    > :is(select, input:not([type='checkbox'], [type='radio'], [type='range'], [type='color'])) {
    min-height: 36px;
    font-size: var(--t-input);
  }
  body.pe-on .overlay-card .pair button {
    min-height: var(--h-touch);
  }
  body.pe-on :where(aside.inspector, .cc-content) .toggles label {
    min-height: var(--h-touch);
    display: inline-flex;
    align-items: center;
  }
  body.pe-on .switch-row > input[type='checkbox'] {
    width: 40px;
    height: 24px;
    background-size:
      18px 18px,
      auto;
    background-position:
      3px 50%,
      0 0;
  }
  body.pe-on .switch-row > input[type='checkbox']:checked {
    background-position:
      calc(100% - 3px) 50%,
      0 0;
  }
  body.pe-on input[type='color'] {
    width: 36px;
    height: 36px;
  }
}
