/* TextQL brand controls.
 *
 * The button, field, slider, toggle and select anatomy, as plain global CSS so
 * that all three apps on this domain can wear it: the Svelte brand kit, /poster
 * and /deck. The Svelte side has thin components that emit these classes rather
 * than restating the styles.
 *
 * WHY THIS EXISTS
 * The factory and the poster maker are the only places on brand.textql.com that
 * show TextQL building an interface, and both shipped with stock browser
 * controls — OS-blue checkboxes, default select chevrons, grey range tracks. A
 * brand kit whose own tools are unbranded is an argument against itself.
 *
 * Anatomy follows the site's BrandButton (landing-page-v2
 * src/lib/components/brand/brandPrimitives.css.ts): a square hairline frame, a
 * mono uppercase label between real bracket glyphs, and four viewfinder corner
 * marks that open 4px on their diagonals on hover. Sizes and easings come from
 * the tokens; nothing here invents a value.
 *
 * Depends on /brand/tokens.css.
 */

/* ---------------------------------------------------------------- register
   The paper/ink flip is three custom properties, not a second set of rules.
   Put `.on-ink` on any ancestor — a dark panel, a photo overlay — and every
   control inside it flips at once. */

.ctl,
.btn,
.field,
.range,
.toggle,
.select,
.app-select {
  --ctl-ink: var(--ink);
  --ctl-paper: var(--paper);
  --ctl-hair: var(--hair);
  --ctl-muted: var(--ink-muted);
  --ctl-surface: var(--surface);
}

.on-ink .ctl,
.on-ink .btn,
.on-ink .field,
.on-ink .range,
.on-ink .toggle,
.on-ink .select,
.on-ink .app-select,
.ctl.on-ink,
.btn.on-ink {
  --ctl-ink: var(--on-ink);
  --ctl-paper: var(--ink);
  --ctl-hair: var(--hair-on-ink);
  --ctl-muted: var(--on-ink-muted);
  --ctl-surface: rgba(248, 248, 248, 0.06);
}

/* ---------------------------------------------------------------- button */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  /* the corner marks seat on the frame's own corners — never round these */
  border-radius: 0;
  border: 1px solid transparent;
  background: transparent;
  color: var(--ctl-ink);
  font-family: var(--font-mono);
  font-size: var(--text-meta);
  font-weight: var(--weight-medium);
  line-height: 1;
  letter-spacing: var(--tracking-widest);
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  padding: var(--space-sm) var(--space-lg);
  transition:
    background var(--motion-fast) var(--motion-ease),
    border-color var(--motion-fast) var(--motion-ease),
    color var(--motion-fast) var(--motion-ease);
  /* corner-mark arm length, overridden by the size modifiers */
  --arm: 7px;
}

.btn--sm {
  font-size: var(--text-micro);
  padding: var(--space-xs) var(--space-sm);
  --arm: 5px;
}

.btn--md {
  font-size: var(--text-body);
  padding: var(--space-lg) var(--space-2xl);
  --arm: 10px;
}

/* kinds */

.btn--bracket {
  border-color: var(--ctl-hair);
}
.btn--bracket:hover:not(:disabled) {
  border-color: var(--ctl-ink);
}

.btn--solid {
  background: var(--ctl-ink);
  border-color: var(--ctl-ink);
  color: var(--ctl-paper);
}

.btn--ghost {
  border-color: transparent;
}

.btn--danger:hover:not(:disabled) {
  border-color: var(--error);
  color: var(--error);
}

.btn:disabled {
  opacity: 0.38;
  cursor: not-allowed;
}

.btn:focus-visible {
  outline: 2px dashed var(--ctl-ink);
  outline-offset: 6px;
}

/* The real bracket glyphs belong to the button, not the label — so the label
   stays clean for anything that reads it. The closing glyph's gap is one track
   short, because the label's last letter already carries a trailing letterspace. */

.btn::before,
.btn::after {
  font: inherit;
  opacity: 0.72;
}
.btn::before {
  content: '[';
  margin-right: 0.6em;
}
.btn::after {
  content: ']';
  margin-left: calc(0.6em - var(--tracking-widest));
}
.btn--plain::before,
.btn--plain::after {
  content: none;
}

/* The viewfinder: four L-marks just outside the frame, opening on hover. Drawn
   with one gradient-free background per corner so a button stays a single
   element and can be a <button>, an <a> or a <label> without extra spans. */

.btn--marks {
  background-image:
    linear-gradient(var(--ctl-ink), var(--ctl-ink)), linear-gradient(var(--ctl-ink), var(--ctl-ink)),
    linear-gradient(var(--ctl-ink), var(--ctl-ink)), linear-gradient(var(--ctl-ink), var(--ctl-ink)),
    linear-gradient(var(--ctl-ink), var(--ctl-ink)), linear-gradient(var(--ctl-ink), var(--ctl-ink)),
    linear-gradient(var(--ctl-ink), var(--ctl-ink)), linear-gradient(var(--ctl-ink), var(--ctl-ink));
  background-repeat: no-repeat;
  /* horizontal arm, vertical arm — per corner, clockwise from top-left */
  background-size:
    var(--arm) 1px, 1px var(--arm), var(--arm) 1px, 1px var(--arm), var(--arm) 1px, 1px var(--arm),
    var(--arm) 1px, 1px var(--arm);
  background-position:
    left -1.5px top -1.5px, left -1.5px top -1.5px, right -1.5px top -1.5px, right -1.5px top -1.5px,
    left -1.5px bottom -1.5px, left -1.5px bottom -1.5px, right -1.5px bottom -1.5px,
    right -1.5px bottom -1.5px;
  background-origin: border-box;
  transition:
    background-position var(--motion-fast) var(--motion-ease),
    border-color var(--motion-fast) var(--motion-ease),
    color var(--motion-fast) var(--motion-ease);
}

.btn--marks:hover:not(:disabled) {
  background-position:
    left -5.5px top -5.5px, left -5.5px top -5.5px, right -5.5px top -5.5px,
    right -5.5px top -5.5px, left -5.5px bottom -5.5px, left -5.5px bottom -5.5px,
    right -5.5px bottom -5.5px, right -5.5px bottom -5.5px;
}

.btn--marks:active:not(:disabled) {
  background-position:
    left 0.5px top 0.5px, left 0.5px top 0.5px, right 0.5px top 0.5px, right 0.5px top 0.5px,
    left 0.5px bottom 0.5px, left 0.5px bottom 0.5px, right 0.5px bottom 0.5px,
    right 0.5px bottom 0.5px;
}

/* solid + marks: the fill hides the marks at rest, so they read as the hover. */
.btn--solid.btn--marks {
  background-color: var(--ctl-ink);
}

/* A bare mono action — no box. For "clear", "reset", tertiary moves. */
.btn--bare {
  border: 0;
  padding: 0;
  color: var(--ctl-muted);
}
.btn--bare:hover:not(:disabled) {
  color: var(--ctl-ink);
}

/* ---------------------------------------------------------------- labels */

.ctl-label {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--ctl-muted);
}

.ctl-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

/* ---------------------------------------------------------------- fields */

.field {
  display: block;
  width: 100%;
  border-radius: 0;
  border: 1px solid var(--ctl-hair);
  background: var(--ctl-surface);
  color: var(--ctl-ink);
  font-family: var(--font-sans);
  font-size: var(--text-small);
  font-weight: var(--weight-regular);
  letter-spacing: var(--tracking-prose);
  line-height: var(--leading-normal);
  padding: var(--space-xs) var(--space-sm);
  resize: vertical;
  transition: border-color var(--motion-fast) var(--motion-ease);
}

.field:hover {
  border-color: var(--ink-soft);
}

.field:focus {
  outline: none;
  border-color: var(--ctl-ink);
}

.field::placeholder {
  color: var(--ctl-muted);
}

.field--mono {
  font-family: var(--font-mono);
  font-size: var(--text-meta);
}

/* ---------------------------------------------------------------- select
   `appearance: none` plus a drawn chevron. Two hairlines rotated into a
   caret rather than an SVG, so the arrow is the same ink at any zoom. */

.select {
  position: relative;
  display: block;
}

.select > select {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  border-radius: 0;
  border: 1px solid var(--ctl-hair);
  background: var(--ctl-surface);
  color: var(--ctl-ink);
  font-family: var(--font-mono);
  font-size: var(--text-meta);
  letter-spacing: var(--tracking-wide);
  line-height: 1;
  padding: var(--space-xs) var(--space-xl) var(--space-xs) var(--space-sm);
  cursor: pointer;
  transition: border-color var(--motion-fast) var(--motion-ease);
}

.select > select:hover {
  border-color: var(--ink-soft);
}

.select > select:focus {
  outline: none;
  border-color: var(--ctl-ink);
}

.select::after {
  content: '';
  position: absolute;
  right: var(--space-sm);
  top: 50%;
  width: 6px;
  height: 6px;
  margin-top: -5px;
  border-right: 1px solid var(--ctl-ink);
  border-bottom: 1px solid var(--ctl-ink);
  transform: rotate(45deg);
  pointer-events: none;
}

/* ---------------------------------------------------------------- range
   A hairline track with a square ink handle. Square, because every other
   corner in this system is. */

.range {
  display: block;
  width: 100%;
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  cursor: pointer;
  /* tall enough to hit on touch, while the visible track stays a hairline */
  height: 18px;
  margin: 0;
}

.range:focus {
  outline: none;
}

.range::-webkit-slider-runnable-track {
  height: 1px;
  background: var(--ink-soft);
}

.range::-moz-range-track {
  height: 1px;
  background: var(--ink-soft);
}

.range::-moz-range-progress {
  height: 1px;
  background: var(--ctl-ink);
}

.range::-webkit-slider-thumb {
  appearance: none;
  -webkit-appearance: none;
  width: 9px;
  height: 9px;
  margin-top: -4px;
  border: 0;
  border-radius: 0;
  background: var(--ctl-ink);
  transition: transform var(--motion-fast) var(--motion-ease);
}

.range::-moz-range-thumb {
  width: 9px;
  height: 9px;
  border: 0;
  border-radius: 0;
  background: var(--ctl-ink);
}

.range:hover::-webkit-slider-thumb,
.range:focus-visible::-webkit-slider-thumb {
  transform: scale(1.25);
}

.range:hover::-moz-range-thumb,
.range:focus-visible::-moz-range-thumb {
  transform: scale(1.25);
}

/* A row: label on the left, live value on the right, track beneath. */
.range-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: var(--space-2xs) var(--space-xs);
}

.range-row .range {
  grid-column: 1 / -1;
}

.range-value {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  font-variant-numeric: tabular-nums;
  color: var(--ctl-ink);
}

/* ---------------------------------------------------------------- toggle
   A checkbox as a bracketed box that fills with ink and shows a paper tick.
   Drawn, not an emoji or an SVG, so it inherits the register. */

.toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--ctl-muted);
  user-select: none;
}

.toggle:hover {
  color: var(--ctl-ink);
}

.toggle > input {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  flex: none;
  width: 13px;
  height: 13px;
  margin: 0;
  border: 1px solid var(--ink-soft);
  border-radius: 0;
  background: var(--ctl-surface);
  cursor: pointer;
  transition:
    background var(--motion-fast) var(--motion-ease),
    border-color var(--motion-fast) var(--motion-ease);
}

.toggle > input:hover {
  border-color: var(--ctl-ink);
}

.toggle > input:checked {
  background: var(--ctl-ink);
  border-color: var(--ctl-ink);
}

.toggle > input:checked::after {
  content: '';
  position: absolute;
  left: 3.5px;
  top: 0.5px;
  width: 4px;
  height: 8px;
  border-right: 1.5px solid var(--ctl-paper);
  border-bottom: 1.5px solid var(--ctl-paper);
  transform: rotate(42deg);
}

.toggle > input:focus-visible {
  outline: 2px dashed var(--ctl-ink);
  outline-offset: 3px;
}

.toggle > input:checked ~ * {
  color: var(--ctl-ink);
}

/* [ brand guidelines ] / 06 poster maker */
.app-crumb {
  display: flex;
  align-items: baseline;
  gap: var(--space-xs);
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--ink-soft);
  white-space: nowrap;
  min-width: 0;
  overflow: hidden;
}

.app-crumb a {
  color: var(--ink-soft);
  text-decoration: none;
}

.app-crumb a:hover {
  color: var(--ink);
}

.app-crumb .here {
  color: var(--ink-muted);
  text-overflow: ellipsis;
  overflow: hidden;
}

/* A select in the bar: same anatomy as the panel's, sized to sit level with the
   small buttons beside it. */
.app-select {
  appearance: none;
  -webkit-appearance: none;
  max-width: 220px;
  border-radius: 0;
  border: 1px solid var(--ctl-hair);
  background: transparent;
  color: var(--ctl-ink);
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  line-height: 1;
  padding: var(--space-xs) var(--space-lg) var(--space-xs) var(--space-sm);
  cursor: pointer;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--ctl-ink) 50%),
    linear-gradient(135deg, var(--ctl-ink) 50%, transparent 50%);
  background-size:
    4px 4px,
    4px 4px;
  background-position:
    right 12px center,
    right 9px center;
  background-repeat: no-repeat;
  transition: border-color var(--motion-fast) var(--motion-ease);
}

.app-select:hover {
  border-color: var(--ctl-ink);
}

.app-select:focus {
  outline: none;
  border-color: var(--ctl-ink);
}

/* A native option list is drawn by the OS, which knows nothing about the dark
   register — so the popup gets the light ground explicitly rather than paper text
   on a paper menu. */
.on-ink .app-select option {
  color: var(--ink);
  background: var(--paper);
}

/* ---------------------------------------------------------------- misc */

/* A hairline separator inside a toolbar. */
.ctl-sep {
  width: 1px;
  align-self: stretch;
  background: var(--ctl-hair);
}

/* Mono meta text — file names, dimensions, keyboard hints. */
.ctl-meta {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--ctl-muted);
}

@media (prefers-reduced-motion: reduce) {
  .btn,
  .btn--marks,
  .field,
  .range::-webkit-slider-thumb,
  .toggle > input {
    transition: none;
  }
}

/* A truncated breadcrumb is noise. Below the tools' own breakpoint the lockup
   alone carries the "you are still on brand.textql.com" job. */
@media (max-width: 720px) {
  .app-crumb {
    display: none;
  }
}
