/* ============================================================
   COMPONENTS — basics   (documented in README.md)

   The small parts every bigger component is built from: avatar,
   button, icon button, pill, file chip, status, count, tooltip,
   key. Tokens only — no raw colours — so every part works in both
   themes and inside a data-theme subtree.
   ============================================================ */

/* ---------- Focus ----------
   One ring for everything interactive: the accent (near-black /
   near-white), offset outward so it never eats the control's edge.
   Keyboard only — a mouse click doesn't draw it. */
:where(.sy-btn, .sy-icon-btn, .sy-pill, .sy-file, .sy-av--btn):focus-visible,
:where(button, a, summary, [tabindex], [role="button"], [role="tab"], [role="option"]):focus-visible {   /* …and every other control */
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
/* Rows inside a menu, a list or a clipped card: the ring goes inside, or the edge would cut it off */
:where(.sy-menu > button, .menu > button, .pop > button, .fmenu > button, .fswmenu button, .mitem, .dopt, .prow button, .dtab, .fcard__main, .fcard__btn, .sy-nav__row button):focus-visible {
  outline-offset: -2px;
}

/* ============ Avatar (a person) ============ */
.sy-av {
  --s: 28px;
  position: relative;
  flex: none;
  display: inline-grid;
  place-items: center;
  width: var(--s);
  height: var(--s);
  border-radius: 50%;
  background: var(--av, var(--selected));
  color: var(--av-ink, var(--text));
  font-size: calc(var(--s) * .38);
  font-weight: var(--weight-strong);
  letter-spacing: .01em;
  line-height: 1;
  user-select: none;
}
.sy-av[data-p="1"] { --av: var(--p1); --av-ink: var(--p1-ink); }
.sy-av[data-p="2"] { --av: var(--p2); --av-ink: var(--p2-ink); }
.sy-av[data-p="3"] { --av: var(--p3); --av-ink: var(--p3-ink); }
.sy-av[data-p="4"] { --av: var(--p4); --av-ink: var(--p4-ink); }
.sy-av[data-p="5"] { --av: var(--p5); --av-ink: var(--p5-ink); }
/* A hairline ring in the person's own hue: the fill is close to white, the ring keeps the edge (#29) */
.sy-av[data-p] { box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--av-ink) 22%, transparent); }
/* A photo, when there is one: <span class="sy-av" data-photo style="--photo:url(…)"> */
.sy-av[data-photo] { background: var(--photo) center / cover no-repeat, var(--av, var(--selected)); color: transparent; box-shadow: inset 0 0 0 1px rgba(0,0,0,.06); }
.sy-av--xs { --s: 16px; }
.sy-av--sm { --s: 20px; }
.sy-av--lg { --s: 36px; }
.sy-av--xs { font-size: 7px; }

/* Presence: a dot cut out of the corner (ring = the surface it sits on). */
.sy-av[data-presence]::after {
  content: "";
  position: absolute;
  right: -1px;
  bottom: -1px;
  width: max(7px, calc(var(--s) * .3));
  height: max(7px, calc(var(--s) * .3));
  border-radius: 50%;
  box-shadow: 0 0 0 2px var(--ring, var(--bg));
}
.sy-av[data-presence="here"]::after  { background: var(--success); }
/* Away is a hollow ring, not a grey dot: a filled grey dot is an agent at work (the nav's
   language, #56), and without motion the two would look the same (#73). */
.sy-av[data-presence="away"]::after  { background: var(--ring, var(--bg)); box-shadow: inset 0 0 0 1.5px color-mix(in oklab, var(--text) 45%, transparent), 0 0 0 2px var(--ring, var(--bg)); }

/* Overflow count at the end of a stack: "+3". */
.sy-av--more { --av: var(--surface); --av-ink: var(--text-muted); font-weight: var(--weight-medium); box-shadow: inset 0 0 0 1px var(--border); }

/* Stack (#74): faces overlap tightly (36% of a face, ≈9px at 26px), each ringed in the surface
   colour so it reads as cut out of the one behind it. The order never changes: each face sits over
   the one to its left, so the rightmost is on top (DOM order; nothing sets a z-index). Hover lifts
   only the face under the pointer, 1px, in place; nothing else moves, so every face stays where
   you aimed (it used to fan the whole stack apart, sliding the target away). */
.sy-stack { display: inline-flex; align-items: center; }
.sy-stack > * {
  margin-left: calc(var(--s, 28px) * -.36);
  box-shadow: 0 0 0 2px var(--ring, var(--bg));
  transition: transform var(--motion-fast) var(--ease);
}
.sy-stack > :first-child { margin-left: 0; }
.sy-stack > :hover { transform: translateY(-1px); }
@media (prefers-reduced-motion: reduce) { .sy-stack > :hover { transform: none; } }

/* Away, in a stack: faded by an opaque wash of the surface it sits on, never by opacity, so the
   face stays solid and the one behind it never shows through. */
.sy-av.is-away::before { content: ""; position: absolute; inset: 0; border-radius: 50%; background: var(--ring, var(--bg)); opacity: .55; pointer-events: none; }

/* Arrival: drops in with a little overshoot and one ring pulse. */
.sy-arrive { animation: syArrive .6s var(--ease-spring) both; }
@keyframes syArrive {
  0%   { transform: scale(.3) translateY(6px); opacity: 0; }
  55%  { opacity: 1; }
  100% { transform: none; opacity: 1; }
}

/* ============ Button ============ */
.sy-btn {
  --h: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: var(--h);
  padding: 0 calc(var(--h) * .38);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
  color: var(--text);
  font-size: var(--font-sm);
  font-weight: var(--weight-medium);
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--motion-instant) var(--ease),
              border-color var(--motion-instant) var(--ease),
              transform var(--motion-instant) var(--ease),
              opacity var(--motion-fast) var(--ease);
}
.sy-btn .ms { --ms-size: 18px; margin-left: -2px; }
.sy-btn:hover { background: var(--surface); border-color: var(--border-strong); }
.sy-btn:active { transform: scale(.97); }

.sy-btn--primary { background: var(--accent); border-color: var(--accent); color: var(--accent-fg); }
.sy-btn--primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.sy-btn--ghost { background: none; border-color: transparent; }
.sy-btn--ghost:hover { background: var(--hover); border-color: transparent; }
.sy-btn--danger { color: var(--danger); }

.sy-btn--sm { --h: 32px; font-size: var(--font-sm); }   /* #36: 28 → 32, 12 → 14 */
.sy-btn--sm .ms { --ms-size: 16px; }
.sy-btn--lg { --h: 40px; font-size: var(--font-base); border-radius: var(--radius-lg); }

.sy-btn:disabled, .sy-btn[aria-disabled="true"] { opacity: .4; pointer-events: none; }
/* Busy: the label stays (so the width doesn't jump); a spinner leads. */
.sy-btn[aria-busy="true"] { pointer-events: none; }
.sy-btn[aria-busy="true"] .ms { display: none; }
.sy-btn[aria-busy="true"]::before {
  content: "";
  width: 13px; height: 13px;
  margin-left: -2px;
  border-radius: 50%;
  border: 1.75px solid color-mix(in srgb, currentColor 30%, transparent);
  border-top-color: currentColor;
  animation: sySpin .8s linear infinite;
}

/* ============ Icon button ============ */
.sy-icon-btn {
  --h: 32px;
  flex: none;
  display: inline-grid;
  place-items: center;
  width: var(--h);
  height: var(--h);
  padding: 0;
  border: 0;
  border-radius: var(--radius-md);
  background: none;
  color: var(--text-muted);
  cursor: pointer;
  transition: background var(--motion-instant) var(--ease),
              color var(--motion-instant) var(--ease),
              transform var(--motion-instant) var(--ease);
}
.sy-icon-btn .ms { --ms-size: 20px; }
.sy-icon-btn:hover { background: var(--hover); color: var(--text); }
.sy-icon-btn:active { transform: scale(.92); }
.sy-icon-btn[aria-pressed="true"] { background: var(--selected); color: var(--text); }
.sy-icon-btn[aria-pressed="true"] .ms { --ms-fill: 1; }
.sy-icon-btn--round { border-radius: 50%; }
.sy-icon-btn--sm { --h: 32px; }
.sy-icon-btn--sm .ms { --ms-size: 20px; }
/* The send button: the one filled circle. */
.sy-icon-btn--send { border-radius: 50%; background: var(--accent); color: var(--accent-fg); }
.sy-icon-btn--send:hover { background: var(--accent-hover); color: var(--accent-fg); }
.sy-icon-btn--send:disabled { opacity: .3; pointer-events: none; }

/* ============ Pill ============ */
.sy-pill {
  --h: 32px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: var(--h);
  padding: 0 12px 0 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);   /* #60: every button-like control shares the button's corner */
  background: var(--surface-raised);
  color: var(--text);
  font-size: var(--font-sm);
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--motion-fast) var(--ease),
              border-color var(--motion-fast) var(--ease),
              color var(--motion-fast) var(--ease),
              transform var(--motion-fast) var(--ease);
}
.sy-pill .ms { --ms-size: 17px; color: var(--text-muted); transition: color var(--motion-fast) var(--ease); }
.sy-pill:hover { background: var(--surface); border-color: var(--border-strong); }
.sy-pill:active { transform: scale(.96); }
.sy-pill[aria-pressed="true"], .sy-pill.is-active { background: var(--accent); border-color: var(--accent); color: var(--accent-fg); }
.sy-pill[aria-pressed="true"] .ms, .sy-pill.is-active .ms { color: var(--accent-fg); }
.sy-pill--sm { --h: 28px; font-size: var(--font-xs); padding: 0 10px 0 8px; }
.sy-pill__x { --ms-size: 15px !important; margin-right: -4px; opacity: .7; }

/* ============ File chip ============
   Type in the tile; who it came from at the end (a face, or an
   agent's colour). Upload progress runs along the bottom edge. */
.sy-file {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  max-width: 100%;
  height: 44px;
  padding: 0 10px 0 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface-raised);
  font-size: var(--font-xs);
  text-align: left;
  overflow: hidden;
  cursor: pointer;
  transition: border-color var(--motion-fast) var(--ease), box-shadow var(--motion-fast) var(--ease);
}
.sy-file:hover { border-color: var(--border-strong); box-shadow: var(--shadow-raise); }
.sy-file__tile {
  flex: none;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--text-muted);
}
.sy-file__tile .ms { --ms-size: 18px; }
.sy-file__text { display: flex; flex-direction: column; min-width: 0; line-height: 1.3; }
.sy-file__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: var(--weight-medium); color: var(--text); }
.sy-file__meta { color: var(--text-muted); font-size: var(--font-2xs); white-space: nowrap; }
.sy-file .sy-av { --s: 18px; font-size: 7px; margin-left: 4px; }
/* Made by an agent: the tile takes the agent's colour. */
.sy-file[data-agent] .sy-file__tile { background: color-mix(in srgb, var(--c) 14%, transparent); color: var(--c); }
.sy-file__agent { flex: none; width: 8px; height: 8px; margin-left: 6px; border-radius: 50%; background: var(--c); }
/* Uploading: a thin bar fills along the bottom. --p is 0–100. */
.sy-file[data-uploading]::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  height: 2px;
  width: calc(var(--p, 0) * 1%);
  background: var(--accent);
  transition: width .3s var(--ease);
}
.sy-file[data-error] { border-color: color-mix(in srgb, var(--danger) 50%, var(--border)); }
.sy-file[data-error] .sy-file__meta { color: var(--danger); }
.sy-file__x { margin-left: 2px; }

/* ============ Status (nav rows, headers) ============ */
.sy-status { flex: none; display: inline-grid; place-items: center; width: 16px; height: 16px; }
.sy-status--unread::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); }
.sy-status--mention { width: auto; min-width: 16px; padding: 0 4px; border-radius: var(--radius-full); background: var(--accent); color: var(--accent-fg); font-size: 10px; font-weight: var(--weight-strong); }
.sy-status--done .ms { --ms-size: 16px; color: var(--success); }
.sy-spin {
  flex: none;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  border: 1.75px solid color-mix(in srgb, var(--text-muted) 30%, transparent);
  border-top-color: var(--text);
  animation: sySpin .8s linear infinite;
}
@keyframes sySpin { to { transform: rotate(360deg); } }

/* ============ Count ============ */
.sy-count {
  display: inline-grid;
  place-items: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: var(--radius-full);
  background: var(--selected);
  color: var(--text);
  font-size: var(--font-2xs);
  font-weight: var(--weight-medium);
  font-variant-numeric: tabular-nums;
}
.sy-count--strong { background: var(--accent); color: var(--accent-fg); }

/* ============ Tooltip ============
   Any element with data-tip. Inverse colours, a short delay in so a
   pointer passing through doesn't flash it, instant out. */
[data-tip] { position: relative; }
[data-tip]::after {
  content: attr(data-tip);
  position: absolute;
  left: 50%;
  bottom: calc(100% + 8px);
  z-index: 40;
  padding: 5px 8px;
  border-radius: var(--radius-sm);
  background: var(--text);
  color: var(--bg);
  font-size: var(--font-xs);
  font-weight: var(--weight-medium);
  line-height: 1.2;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, 3px);
  translate: var(--tip-dx, 0px) 0;   /* theme.js nudges a tip back inside whatever would cut it off */
  transition: opacity var(--motion-fast) var(--ease), transform var(--motion-fast) var(--ease);
}
[data-tip]:hover::after, [data-tip]:focus-visible::after {
  opacity: 1;
  transform: translate(-50%, 0);
  transition-delay: .35s;
}
[data-tip-pos="below"]::after { bottom: auto; top: calc(100% + 8px); transform: translate(-50%, -3px); }
/* Right: beside the button, for when below would land on something (the nav's Show button: the nav peeks in below it) */
[data-tip-pos="right"]::after { left: calc(100% + 8px); bottom: auto; top: 50%; transform: translate(-3px, -50%); }
[data-tip-pos="right"]:hover::after, [data-tip-pos="right"]:focus-visible::after { transform: translate(0, -50%); }

/* ============ Key (shortcuts) ============ */
.sy-kbd {
  display: inline-grid;
  place-items: center;
  min-width: 20px;
  height: 20px;
  padding: 0 5px;
  border: 1px solid var(--border);
  border-bottom-width: 2px;
  border-radius: 5px;
  background: var(--surface-raised);
  color: var(--text-muted);
  font-family: var(--font-ui);
  font-size: var(--font-2xs);
  font-weight: var(--weight-medium);
}

@media (prefers-reduced-motion: reduce) {
  .sy-arrive, .sy-spin, .sy-btn[aria-busy="true"]::before { animation: none !important; }
}

/* ---------- Screen-reader only ---------- */
.sy-sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* ---------- Shared motion ---------- */
/* Sweep (#56, #74): a running label's shimmer. The nav's running session and the participants list use it. */
@keyframes sySweep { from { background-position: 100% 0; } to { background-position: -180% 0; } }
/* Breathe (#56): the grey working dot, slowly (the nav's "pulseonly" state, Sessions) */
@keyframes syBreathe { 0%, 100% { transform: scale(.7); opacity: .45; } 50% { transform: scale(1); opacity: 1; } }
