/* ═══════════════════════════════════════════════════════════════════════════
   base.css, reset, typography, and the accessibility floor.

   Loaded after tokens.css, before components.css. Nothing here is specific to
   a page; everything applies to every surface Veylo renders.
   ═══════════════════════════════════════════════════════════════════════════ */

*,
*::before,
*::after { box-sizing: border-box; }

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  /* Smooth scrolling is a nicety, not a default, it makes long jumps
     disorienting and fights with keyboard navigation. Only the marketing
     page's in-page anchors opt in (see marketing.css). */
}

body {
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: var(--lh-normal);
  color: var(--text);
  background: var(--canvas);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  min-height: 100vh;
}

[hidden] { display: none !important; }

img, svg, video, canvas {
  display: block;
  max-width: 100%;
}

svg { flex-shrink: 0; }

/* Inherit the type stack instead of the browser's, in every control. */
button, input, select, textarea {
  font: inherit;
  color: inherit;
}

/* ── Headings ─────────────────────────────────────────────────────────────
   Sizes are set by the components that use them. Here we only establish the
   shared shape: tight leading, slightly negative tracking, balanced wrapping
   so a two-line title never leaves one orphan word. */
h1, h2, h3, h4, h5, h6 {
  font-weight: var(--fw-bold);
  line-height: var(--lh-tight);
  letter-spacing: var(--tracking-tight);
  text-wrap: balance;
}

h1 { font-size: var(--fs-title-lg); }
h2 { font-size: var(--fs-title); }
h3 { font-size: var(--fs-title-sm); }
h4, h5, h6 { font-size: var(--fs-body); }

p { text-wrap: pretty; }

/* ── Links ────────────────────────────────────────────────────────────────
   Underlined by default in prose so they are distinguishable without relying
   on colour (WCAG 1.4.1). Links inside chrome opt out with .link-plain. */
a {
  color: var(--brand);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}
a:hover { color: var(--brand-hover); }

.link-plain {
  color: inherit;
  text-decoration: none;
}
.link-plain:hover { color: inherit; }

/* ── Code ─────────────────────────────────────────────────────────────── */
code, kbd, samp, pre {
  font-family: var(--font-mono);
  font-size: 0.92em;
}

code:not(pre code) {
  padding: 0.1em 0.35em;
  border-radius: var(--radius-sm);
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  /* IDs and keys are long and unbreakable; let them wrap rather than force a
     horizontal scrollbar onto the whole page. */
  overflow-wrap: anywhere;
}

kbd {
  display: inline-block;
  min-width: 1.5em;
  padding: 0.1em 0.4em;
  text-align: center;
  font-size: var(--fs-caption);
  color: var(--text-secondary);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-bottom-width: 2px;
  border-radius: var(--radius-sm);
}

/* ── Focus ────────────────────────────────────────────────────────────────
   The single most important rule in this file. The previous stylesheet had one
   :focus declaration across 1375 lines and none for buttons, links, tabs or
   menu items, keyboard users had nothing to follow.

   :focus-visible rather than :focus, so a mouse click on a button does not
   leave a ring behind, but Tab always does. */
:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* Never remove the outline without replacing it. Elements that need a custom
   ring set it themselves via the .focus-ring helper below. */
:focus:not(:focus-visible) { outline: none; }

.focus-ring:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
  box-shadow: 0 0 0 4px var(--focus-halo);
}

/* Inset variant for elements flush against a container edge, where an offset
   ring would be clipped (list rows, table cells, tab strips). */
.focus-inset:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: -2px;
}

/* ── Skip link ────────────────────────────────────────────────────────────
   First focusable element on every page. Off-screen until focused. */
.skip-link {
  position: absolute;
  top: var(--sp-2);
  left: var(--sp-2);
  z-index: var(--z-toast);
  padding: var(--sp-2) var(--sp-4);
  background: var(--brand);
  color: var(--text-on-brand);
  font-weight: var(--fw-semibold);
  border-radius: var(--radius);
  text-decoration: none;
  transform: translateY(-200%);
  transition: transform var(--dur-fast) var(--ease-out);
}
.skip-link:focus {
  transform: translateY(0);
  color: var(--text-on-brand);
}

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

/* Visible again when focused, for controls that are hidden until reached. */
.sr-only-focusable:not(:focus):not(:focus-within) {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── Selection ────────────────────────────────────────────────────────── */
::selection {
  background: var(--brand-subtle);
  color: var(--brand-subtle-fg);
}

/* ── Scrollbars ───────────────────────────────────────────────────────── */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
}
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: var(--radius-full);
  border: 2px solid transparent;
  background-clip: content-box;
}
*::-webkit-scrollbar-thumb:hover { background-clip: content-box; background-color: var(--text-muted); }

/* ── Touch targets ────────────────────────────────────────────────────────
   Keyed on the input device, not the viewport. A touchscreen laptop at 1400px
   still needs 44px targets; a mouse at 375px does not. */
@media (pointer: coarse) {
  :root {
    --control-height: var(--tap-target);
    --control-height-lg: 48px;
  }
}

/* ── Reduced motion ───────────────────────────────────────────────────────
   Honour the preference by removing motion, but keep transitions functional
   (1ms rather than 0) so transitionend listeners still fire and nothing hangs
   waiting for an animation that never completes. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── Forced colours (Windows high contrast) ─────────────────────────────── */
@media (forced-colors: active) {
  /* Our tinted backgrounds are stripped in forced-colours mode, so status must
     fall back to a border the OS will honour. */
  .chip, .btn, .field-input, .panel { border: 1px solid; }
  :focus-visible { outline: 2px solid Highlight; }
}

/* ── Print ────────────────────────────────────────────────────────────────
   Rosters, logbooks and session sheets get printed. Make that not embarrassing. */
@media print {
  .app-header,
  .app-nav,
  .toast-region,
  .no-print { display: none !important; }

  body { background: #fff; color: #000; font-size: 11pt; }
  .panel { border: 1px solid #999; break-inside: avoid; box-shadow: none; }
  .table-scroll { overflow: visible !important; }
  a[href^='http']::after { content: ' (' attr(href) ')'; font-size: 9pt; color: #555; }
}

/* ── Layout utilities ─────────────────────────────────────────────────────
   A deliberately small set. Anything used more than a handful of times becomes
   a component instead. */
.stack        { display: flex; flex-direction: column; gap: var(--sp-4); }
.stack-sm     { display: flex; flex-direction: column; gap: var(--sp-2); }
.row          { display: flex; align-items: center; gap: var(--sp-2); }
.row-between  { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); }
.row-wrap     { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.grow         { flex: 1; min-width: 0; }
.truncate     { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.prose        { max-width: var(--prose-max); }

.text-muted     { color: var(--text-muted); }
.text-secondary { color: var(--text-secondary); }
.text-small     { font-size: var(--fs-small); }
.text-caption   { font-size: var(--fs-caption); }
.text-mono      { font-family: var(--font-mono); }
.text-danger    { color: var(--danger); }
.text-success   { color: var(--success); }
.text-warning   { color: var(--warning); }

/* Numeric columns line up only if the digits are the same width. */
.tabular { font-variant-numeric: tabular-nums; }
