/* Primitives: four interactive primitives, the window, cursor and toast. */

/* 1. Primary button */
.btn-primary {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-5);
  background: var(--btn-primary-bg);
  color: var(--btn-primary-text);
  border-radius: var(--btn-radius);
  box-shadow: var(--btn-primary-shadow);
  font-family: var(--font-mono);
  font-size: var(--type-meta);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: var(--meta-tracking);
  transform: translate(0, 0);
  transition:
    box-shadow var(--motion-state),
    transform var(--motion-state),
    background-color var(--motion-state);
}

.btn-primary:hover {
  background: var(--action-hover);
  box-shadow: var(--btn-primary-shadow-hv);
  transform: translate(-1px, -1px);
}

.btn-primary:active {
  box-shadow: var(--btn-primary-shadow-ac);
  transform: translate(3px, 3px);
  transition-duration: var(--dur-press);
}

.btn-primary:focus-visible {
  outline: var(--focus-outline);
  outline-offset: var(--focus-offset);
}

.btn-primary[disabled],
.btn-primary[aria-disabled="true"] {
  background: var(--state-disabled);
  color: var(--text-meta);
  box-shadow: none;
  transform: none;
  cursor: not-allowed;
}

/* 2. Secondary button */
.btn-secondary {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-5);
  background: var(--btn-secondary-bg);
  color: var(--btn-secondary-text);
  border: 1px solid var(--btn-secondary-border);
  border-radius: var(--btn-radius);
  font-family: var(--font-mono);
  font-size: var(--type-meta);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: var(--meta-tracking);
  transform: translate(0, 0);
  transition:
    background-color var(--motion-state),
    border-color var(--motion-state),
    transform var(--motion-state);
}

.btn-secondary:hover {
  background: var(--btn-secondary-bg-hv);
  border-color: var(--border-accent);
  transform: translate(-1px, -1px);
}

.btn-secondary:active {
  transform: translate(2px, 2px);
  transition-duration: var(--dur-press);
}

.btn-secondary:focus-visible {
  outline: var(--focus-outline);
  outline-offset: var(--focus-offset);
}

/* 3. Inline link. Accent enters through the rule, never the text colour. */
.link-inline {
  color: var(--link-color);
  box-shadow: inset 0 -1px 0 var(--link-underline);
  transition: box-shadow var(--motion-state);
}

.link-inline:hover {
  box-shadow: inset 0 -2px 0 var(--link-underline-hv);
}

.link-inline:active {
  box-shadow: inset 0 -1px 0 var(--action-pressed);
  transition-duration: var(--dur-press);
}

.link-inline:focus-visible {
  outline: var(--focus-outline);
  outline-offset: var(--focus-offset);
  box-shadow: none;
}

/* 4. System control. --ctrl-tint is read by cursor.js. */
.ctrl {
  display: inline-grid;
  place-items: center;
  width: var(--ctrl-size);
  height: var(--ctrl-size);
  border: 1px solid var(--ctrl-border);
  border-radius: var(--radius-os);
  background: transparent;
  color: var(--text-meta);
  transition:
    background-color var(--motion-state),
    border-color var(--motion-state),
    color var(--motion-state);
}

.ctrl:hover {
  background: var(--ctrl-bg-hv);
  border-color: var(--ctrl-tint, var(--border-accent));
  color: var(--ctrl-tint, var(--text-accent));
}

.ctrl:active {
  background: var(--action-pressed);
  transition-duration: var(--dur-press);
}

.ctrl:focus-visible {
  outline: var(--focus-outline);
  outline-offset: 2px;
}

/* Window control variants removed with the controls themselves. D-065. */

/* Signature element: the inspection window. Instrument layer, no pop shapes. */
.win {
  background: var(--window-bg);
  border: 1px solid var(--window-border);
  border-radius: var(--window-radius);
  box-shadow: var(--window-shadow);
  overflow: hidden;
}

.win-titlebar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-2) var(--space-3);
  background: var(--window-titlebar-bg);
  border-bottom: 1px solid var(--window-border);
}

.win-label {
  font-family: var(--font-system);
  font-size: var(--type-chrome);
  color: var(--window-label-color);
  letter-spacing: 0.02em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Sized in rem, not em: em would take the container body, 17px. */
.win-icon {
  width: calc(var(--type-chrome) * 1.2);
  height: calc(var(--type-chrome) * 1.2);
  flex-shrink: 0;
  fill: currentColor;
  color: var(--window-label-color);
}

/* Path root drops on phones: two RUNE-TALES labels needed 282px for 237. */
@media (max-width: 640px) {
  .win-root { display: none; }
}

/* .win-controls removed with them: a container with no possible content. */

.win-body { padding: var(--space-5); }

/* Family accent lives on the title bar, never on the window body. */
.win--accent .win-titlebar {
  border-bottom-color: var(--win-accent, var(--border-accent));
  box-shadow: inset 0 -2px 0 var(--win-accent, var(--border-accent));
}

/* Badge */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-2);
  background: var(--badge-bg);
  border: 1px solid var(--badge-border);
  border-radius: var(--radius-os);
  color: var(--badge-text);
  font-family: var(--font-mono);
  font-size: var(--type-meta);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: var(--meta-tracking);
}

.badge--pop { border-radius: var(--radius-pop); }

/* NEW is a state, the one use that allows accent on a badge. */
.badge--state {
  background: var(--action-default);
  border: 0;
  color: var(--text-on-action);
}

/* Title bar has 22px of usable height; the badge asked for 28. */
.win-titlebar .badge {
  padding-block: 0;
  margin-left: auto;
  flex-shrink: 0;
}

/* Cursor. A dot exactly under the pointer, and a ring that reads its state.
   Position arrives as two CSS variables written in the pointer event itself:
   nothing is interpolated, so neither part can fall behind the pointer. */
.cur {
  position: fixed;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  pointer-events: none;
  z-index: var(--z-cursor);
  will-change: transform;

  /* Written by the engine, the only channel it has into this file. */
  --cur-x: 0px;
  --cur-y: 0px;
  transform: translate3d(var(--cur-x), var(--cur-y), 0);
  /* No transition on this transform. That would be the lag we are removing. */

  /* Resolved once per surface, so each state rule stays a single line. */
  --cur-dot:        var(--cursor-dot-color);
  --cur-ring:       var(--cursor-ring-color);
  --cur-ring-hover: var(--cursor-ring-color-active);
  --cur-edge:       var(--cursor-edge-color);
}

/* Inverted surface: the engine sets this from [data-surface]. */
.cur.is-on-inverted {
  --cur-dot:        var(--cursor-dot-color-inverted);
  --cur-ring:       var(--cursor-ring-color-inverted);
  --cur-ring-hover: var(--cursor-ring-color-active-inverted);
  --cur-edge:       var(--cursor-edge-color-inverted);
}

.cur::before,
.cur::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  border-radius: var(--radius-pop);
}

/* The dot. It only answers the click: it is what says where the click lands. */
.cur::before {
  width: var(--cursor-dot-size);
  height: var(--cursor-dot-size);
  margin: calc(var(--cursor-dot-size) / -2);
  background-color: var(--cur-dot);
  /* Blur 0: an outline, not a drop shadow. Keeps the dot readable on any ground. */
  box-shadow: 0 0 0 var(--cursor-edge-size) var(--cur-edge);
  transition:
    transform var(--motion-feedback),
    background-color var(--motion-state);
}

/* The ring. Answers by scale only: an animated width would ask for layout. */
.cur::after {
  width: var(--cursor-ring-size);
  height: var(--cursor-ring-size);
  margin: calc(var(--cursor-ring-size) / -2);
  border: var(--cursor-ring-line) solid var(--cur-ring);
  /* Outside and inside, so the stroke reads whichever way the ground goes. */
  box-shadow:
    0 0 0 var(--cursor-edge-size) var(--cur-edge),
    inset 0 0 0 var(--cursor-edge-size) var(--cur-edge);
  transition:
    transform var(--motion-feedback),
    border-color var(--motion-state),
    opacity var(--motion-state);
}

/* States. The ring closes in on the dot, then pops back out under the press. */
.cur.is-interactive::after {
  transform: scale(var(--cursor-ring-hover));
  border-color: var(--cur-ring-hover);
}

.cur.is-card::after {
  transform: scale(var(--cursor-ring-card));
  border-color: var(--cur-tint, var(--cur-ring-hover));
}

.cur.is-control::after {
  transform: scale(var(--cursor-ring-control));
  border-color: var(--cur-tint, var(--cur-ring-hover));
}

/* After the states on purpose: same specificity, the press has the last word. */
.cur.is-pressed::before { transform: scale(var(--cursor-dot-press)); }
.cur.is-pressed::after {
  transform: scale(var(--cursor-ring-press));
  border-color: var(--cursor-ring-color-pressed);
}

/* Scrolling is not aiming: the ring steps back, the dot stays exact. */
.cur.is-scrolling::after { opacity: var(--cursor-ring-scroll); }

/* Native I-beam takes over in text. */
.cur.is-hidden { opacity: 0; }

.has-custom-cursor,
.has-custom-cursor a,
.has-custom-cursor button { cursor: none; }

/* Native pointer only when the custom cursor is off. */
html:not(.has-custom-cursor) summary { cursor: pointer; }

.has-custom-cursor input,
.has-custom-cursor textarea,
.has-custom-cursor select,
.has-custom-cursor [contenteditable="true"] { cursor: auto; }

.has-custom-cursor [data-cursor="text"] { cursor: text; }

/* Toast. Not wired to achievements.js yet. D-010. */
.toast-layer {
  position: fixed;
  right: var(--space-5);
  bottom: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  z-index: var(--z-toast);
  pointer-events: none;
}

.toast {
  display: grid;
  gap: var(--space-1);
  padding: var(--space-3) var(--space-4);
  min-width: 220px;
  background: var(--toast-bg);
  border: 1px solid var(--toast-border);
  border-radius: var(--radius-os);
  box-shadow: var(--elevation-window);
  color: var(--toast-text);
}

.toast-label { color: var(--text-accent); }

.toast-title {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: var(--type-small);
}

.toast-desc {
  font-family: var(--font-body);
  font-size: var(--type-small);
  color: var(--text-secondary);
}

/* Icon sized from its text. D-161. */
.ico {
  display: inline-block;
  width: 1.15em;
  height: 1.15em;
  vertical-align: -0.18em;
  flex-shrink: 0;
}
