/*
  Design tokens. The single source of truth is docs/engineering/design-system.md; nothing below
  invents a value that is not in that document.

  Fonts are self-hosted Latin subsets (SIL Open Font License) under wwwroot/fonts/. The stacks
  still name system faces after them so a failed font file does not leave the page unstyled.
*/

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/inter-latin-wght-normal.woff2") format("woff2");
}

@font-face {
  font-family: "Source Serif 4";
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url("../fonts/source-serif-4-latin-wght-normal.woff2") format("woff2");
}

@font-face {
  font-family: "Source Serif 4";
  font-style: italic;
  font-weight: 200 900;
  font-display: swap;
  src: url("../fonts/source-serif-4-latin-wght-italic.woff2") format("woff2");
}

:root {
  /* Colour — raw values. Semantic aliases below always point at these. */
  --paper: #ffffff;
  --paper-sunken: #f7f6f3;
  --paper-writer: #f0efec;
  --ink: #242424;
  --muted: #6b6b6b;
  --rule: #e6e5e1;
  --rule-soft: #f1f0ec;
  --accent: #2c4a3e;
  --accent-cta: #a3471a;
  --danger: #a33b2b;
  --focus: #2c4a3e;
  /* Sits under every photograph, so a slow or broken image is a warm plate, not a white hole. */
  --media-wash: #eae8e3;

  /* Type */
  --font-ui: "Inter", "IBM Plex Sans", ui-sans-serif, system-ui, sans-serif;
  --font-chrome: var(--font-ui);
  --font-article: "Source Serif 4", Charter, Georgia, "Times New Roman", serif;
  --font-mono: "IBM Plex Mono", ui-monospace, monospace;
  --font-code: var(--font-mono);

  --text-xs: 0.8125rem;
  --text-xs-lh: 1.4;
  --text-sm: 0.875rem;
  --text-sm-lh: 1.45;
  --text-md: 1rem;
  --text-md-lh: 1.5;
  --text-lg: 1.25rem;
  --text-lg-lh: 1.6;
  /* Article body on narrow viewports. Never below this: 1.125rem is the floor for body serif. */
  --text-lg-narrow: 1.125rem;
  --text-xl: 1.375rem;
  --text-xl-lh: 1.5;
  --text-2xl: 1.625rem;
  --text-2xl-lh: 1.3;
  --text-3xl: 2rem;
  --text-3xl-lh: 1.25;
  --text-display: 3rem;
  --text-display-lh: 1.12;
  --text-hero: 4rem;
  --text-hero-lh: 1.05;

  /* Tracking — large type tightens, small caps opens. */
  --tracking-hero: -0.03em;
  --tracking-display: -0.022em;
  --tracking-title: -0.014em;
  --tracking-body: -0.003em;
  --tracking-caps: 0.09em;

  /* Space — 4px base */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.25rem;
  --space-6: 1.5rem;
  --space-8: 2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
  --space-16: 4rem;
  --space-20: 5rem;
  --space-24: 6rem;

  /* Measure */
  --measure-article: 42.5rem;
  --measure-media: 56rem;
  --measure-wide: 72rem;
  --measure-writer: 48rem;
  --sidebar-writer: 16rem;

  /* Image ratios — the reader crops to these, so a mixed library still reads as one publication. */
  --ratio-band: 3 / 1;
  --ratio-hero: 2 / 1;
  --ratio-media: 3 / 2;
  --ratio-card: 3 / 2;
  --ratio-grid: 16 / 9;
  --ratio-thumb: 1 / 1;
  --ratio-portrait: 3 / 4;

  /* Radius */
  --radius-control: 4px;
  --radius-pill: 999px;
  --radius-none: 0;

  /* Zinc chrome for Studio (.writer-root) and account (.auth-root). */
  --studio-canvas: #fafafa;
  --studio-surface: #ffffff;
  --studio-ink: #09090b;
  --studio-muted: #71717a;
  --studio-sidebar-fg: #3f3f46;
  --studio-border: #e4e4e7;
  --studio-hover: #f4f4f5;
  --studio-primary: #18181b;
  --studio-primary-hover: #27272a;
  --radius-studio: 0.75rem;
  --radius-studio-card: 0.5rem;
  --radius-studio-control: 0.375rem;
  --shadow-studio: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  /* Popovers / select menus (shadcn SelectContent shadow-md). */
  --shadow-popover: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);

  /* Motion */
  --duration-ui: 150ms;
  --easing-ui: ease;
  --duration-media: 500ms;
  --easing-media: cubic-bezier(0.2, 0.6, 0.2, 1);
  /* Deterrent on reader photographs without a granting workspace subscription. Not DRM. */
  --blur-media: 1.25rem;

  /* Z-index — writer menus, and the in-article gallery viewer (native dialog is top layer). */
  --z-header: 100;
  --z-dropdown: 200;
  --z-dialog: 300;

  /* Semantic aliases. Components use these, never a hex. */
  --bg: var(--paper);
  --bg-sunken: var(--paper-sunken);
  --fg: var(--ink);
  --border: var(--rule);
  --border-soft: var(--rule-soft);
  --link: var(--accent);
}

[data-theme="reader"] {
  --bg: var(--paper);
  --bg-sunken: var(--paper-sunken);
  --fg: var(--ink);
  --border: var(--rule);
  --link: var(--ink);
  --focus: var(--studio-primary);
}

[data-theme="writer"] {
  --bg: var(--paper-writer);
  --bg-sunken: var(--paper-writer);
  --fg: var(--ink);
  --border: var(--rule);
  --link: var(--accent);
}

/* Studio and account. Bare [data-theme="writer"] stays on --paper-writer. */
.writer-root,
.auth-root {
  --bg: var(--studio-canvas);
  --bg-sunken: var(--studio-hover);
  --fg: var(--studio-ink);
  --ink: var(--studio-ink);
  --muted: var(--studio-muted);
  --border: var(--studio-border);
  --border-soft: var(--studio-hover);
  --link: var(--studio-ink);
  --focus: var(--studio-primary);
  --radius-control: var(--radius-studio-control);
}

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

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-ui);
  font-size: var(--text-md);
  line-height: var(--text-md-lh);
  /* The UI grotesque is drawn for this; without it the chrome looks heavier than the article. */
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--link);
}

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

/* Blazor FocusOnNavigate prefers [data-autofocus], then the page title. Titles are not controls. */
h1:focus,
h1:focus-visible {
  outline: none;
}

img {
  max-width: 100%;
  height: auto;
}

hr {
  border: 0;
  border-top: 1px solid var(--border);
  margin: var(--space-8) 0;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
