/* components.css — the components every DevKoe page shares: the focus ring, the reduced-motion rule,
   the skip link, the brand lockup, the eyebrow label, the buttons and the theme toggle. Linked after
   tokens.css and before the page's own layout sheet (site.css, legal.css). It invents no values —
   every colour, size, radius and shadow pulls a token. */

/* ── Focus ring ─────────────────────────────────────────────────────────────────────────────────
   Drawn with `outline`, never box-shadow. A shadow ring is silently cancelled by any later rule that
   sets box-shadow for its own reasons — .btn does, at the same specificity — which leaves a control
   focusable with nothing visible to show for it. An outline cannot be overwritten by a shadow, follows
   the element's own border-radius, and does not change its shape. */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ── Reduced motion ─────────────────────────────────────────────────────────────────────────────
   A property rule rather than a list of animated selectors, so it cannot be outgrown by the next
   animated thing. Durations are collapsed rather than set to `animation: none`: a keyframe that never
   runs leaves an element on its `from` frame — app-shell's `rise` starts at opacity 0 — so collapsing
   the duration is the difference between "no motion" and "no content". */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── Skip link ──────────────────────────────────────────────────────────────────────────────────
   Invisible to a mouse, the first thing a Tab finds. Hidden by POSITION rather than by transform: a
   transform reveal can be quietly beaten by an ancestor's own transform or animation, and `top` cannot.
   `:focus`, not `:focus-visible` — a skip link is only ever reached by keyboard and should appear
   whenever it holds focus, not only when the heuristic agrees. */
.skip-link {
  position: absolute;
  left: var(--space-4);
  top: -6rem;
  z-index: 60;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 1.1rem;
  background: var(--surface);
  color: var(--ink-heading);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-md);
  font-size: var(--text-sm);
  font-weight: 700;
  text-decoration: none;
  transition: top 0.16s var(--ease);
}
.skip-link:focus { top: var(--space-4); }

/* ── Brand lockup ───────────────────────────────────────────────────────────────────────────────
   Mark + wordmark. The mark is sized here rather than by the SVG's width/height attributes so the
   narrowest phone can run it smaller; 24rem puts the full-size lockup back. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.5ch;
  min-height: 44px;
  margin-right: auto;                 /* the lockup sits left; everything after it is pushed right */
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink-heading);
  text-decoration: none;
}
.brand-mark { flex: none; display: block; width: 26px; height: 26px; }
@media (min-width: 24rem) {
  .brand { font-size: var(--text-xl); }
  .brand-mark { width: 30px; height: 30px; }
}
/* a single italic, teal accent word — the display flourish, in headings and in the wordmark's "Koe" */
.accent { font-style: italic; color: var(--accent); }

/* ── Eyebrow ────────────────────────────────────────────────────────────────────────────────────*/
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.5ch;
  margin: 0 0 var(--space-3);
  padding: 0.3rem 0.7rem;
  border-radius: var(--radius-pill);
  background: var(--accent-soft);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--accent);
  /* A long eyebrow wraps on every phone, and an unbalanced wrap inside a pill reads as a broken pill
     rather than a label: a full line, then two words on a stub. Progressive enhancement. */
  text-wrap: balance;
}

/* ── Buttons ────────────────────────────────────────────────────────────────────────────────────
   The primary action is the deep-navy pill that lifts off the page — the brand "ink" CTA. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5ch;
  min-height: 52px;                   /* >=44px tap target */
  padding: 0 1.6rem;
  background: linear-gradient(180deg, color-mix(in srgb, var(--ink) 88%, #fff 12%), var(--ink));
  color: var(--on-ink);
  border: 0;
  border-radius: var(--radius-pill);
  font-family: inherit;
  font-size: var(--text-md);
  font-weight: 650;
  letter-spacing: 0.01em;
  text-decoration: none;
  cursor: pointer;
  box-shadow: var(--shadow-btn);
  transition: transform 0.12s var(--ease), box-shadow 0.2s var(--ease), filter 0.2s var(--ease);
}
.btn:hover { filter: brightness(1.07); box-shadow: var(--shadow-btn), 0 10px 26px -8px color-mix(in srgb, var(--ink) 50%, transparent); }
.btn:active { transform: translateY(1px) scale(0.997); }
.btn[disabled] { opacity: 0.55; cursor: default; filter: none; box-shadow: var(--shadow-sm); }

/* The quiet outline pill. Its label is --ink-heading, NOT --ink: --ink is a band colour that stays a
   deep navy in dark mode so the header and the primary pill keep their weight, and as a label on the
   dark --surface it measures 1.36:1 — an invisible button, not a quiet one. --ink-heading is the
   token that exists for exactly this (ink on light, light ink on dark). */
.btn.secondary {
  background: var(--surface);
  border: 1px solid var(--line);
  color: var(--ink-heading);
  box-shadow: var(--shadow-sm);
}
.btn.secondary:hover { filter: none; box-shadow: var(--shadow-sm); border-color: color-mix(in srgb, var(--teal) 55%, var(--line)); color: var(--accent); }

/* ── Theme toggle ───────────────────────────────────────────────────────────────────────────────
   An icon button wired by theme.js. aria-pressed is authoritative: pressed means dark is active, so
   the sun shows (the action is "go light"); otherwise the moon. The icon strokes are currentColor,
   which is why the colour is --ink-heading and not --ink (invisible in dark, as with .btn.secondary). */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;                         /* 44x44 is a tap target: a flex row must not squeeze it */
  width: 44px;
  height: 44px;
  padding: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--ink-heading);
  cursor: pointer;
  transition: color 0.18s var(--ease), border-color 0.18s var(--ease), transform 0.12s var(--ease);
}
.theme-toggle:hover { color: var(--accent); border-color: color-mix(in srgb, var(--teal) 55%, var(--line)); }
.theme-toggle:active { transform: translateY(1px); }
.theme-toggle svg { width: 20px; height: 20px; }
.theme-toggle .icon-sun { display: none; }
.theme-toggle[aria-pressed="true"] .icon-sun { display: block; }
.theme-toggle[aria-pressed="true"] .icon-moon { display: none; }
