/* ==================================================================================================
   Birge design system — foundation (tokens, fonts, base elements, utilities, motion)
   Owner: design-system agent. Feature CSS lives in static/css/pages/<feature>.css and must use the
   tokens below (var(--…)), never raw hex colors.

   Files (all linked from templates/base.html, in this order — no @import chains):
     css/app.css              tokens · @font-face · reset · typography · icons · utilities · motion
     css/core/shell.css       app shell: sidebar, topbar, tab bar, page, layouts (project/settings/auth/marketing)
     css/core/controls.css    buttons, inputs, checkbox/radio/switch, check-circle, segmented, fields, pickers
     css/core/content.css     cards, lists, tables, chips, badges, avatars, progress, skeleton, empty state…
     css/core/overlays.css    menus/popovers, tooltips, modal, drawer, toasts, shortcut sheet
     css/core/domain.css      task card/row, priority, due chip, project/label/user chips, drag & drop
     css/pages/*.css          feature styles (people, projects, tasks, insights, schedule; landing)

   Theme: <html data-theme="system|light|dark">. Colors are defined ONCE with light-dark(); the
   `color-scheme` of :root decides which side applies (system follows the OS).
   Breakpoints (mobile-first, min-width): sm 640 · md 768 · lg 1024 · xl 1280 · 2xl 1536.
   ================================================================================================== */

/* --------------------------------------------------------------------------------------------------
   1. Fonts — Inter (variable, OFL) for platforms without San Francisco. Kyrgyz needs cyrillic-ext
      (ң ө ү). Files: static/fonts/inter/ (from @fontsource-variable/inter 5.3.0).
   -------------------------------------------------------------------------------------------------- */
@font-face {
  font-family: "InterVariable";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/inter/inter-cyrillic-ext-wght-normal.251d36f2b5a6.woff2") format("woff2");
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: "InterVariable";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/inter/inter-cyrillic-wght-normal.de93fdc85e3d.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "InterVariable";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/inter/inter-latin-ext-wght-normal.1ad231aac0a8.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308,
    U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
    U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "InterVariable";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/inter/inter-latin-wght-normal.260c81a4759b.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
    U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* --------------------------------------------------------------------------------------------------
   2. Tokens
   -------------------------------------------------------------------------------------------------- */
:root {
  color-scheme: light dark;

  /* Palette — Apple system colors (light, dark). Use via data-color="<name>" → --tone. */
  --c-blue: light-dark(#007aff, #0a84ff);
  --c-indigo: light-dark(#5856d6, #5e5ce6);
  --c-purple: light-dark(#af52de, #bf5af2);
  --c-pink: light-dark(#ff2d55, #ff375f);
  --c-red: light-dark(#ff3b30, #ff453a);
  --c-orange: light-dark(#ff9500, #ff9f0a);
  --c-yellow: light-dark(#ffcc00, #ffd60a);
  --c-green: light-dark(#34c759, #30d158);
  --c-mint: light-dark(#00c7be, #63e6e2);
  --c-teal: light-dark(#30b0c7, #40c8e0);
  --c-cyan: light-dark(#32ade6, #64d2ff);
  --c-brown: light-dark(#a2845e, #ac8e68);
  --c-gray: light-dark(#8e8e93, #8e8e93);

  /* "Ink" variants — accessible text/icon color on tinted (soft) backgrounds (WCAG AA). */
  --c-blue-ink: light-dark(#0040dd, #5eadff);
  --c-indigo-ink: light-dark(#3634a3, #8e8cff);
  --c-purple-ink: light-dark(#8944ab, #da8fff);
  --c-pink-ink: light-dark(#c4093f, #ff6482);
  --c-red-ink: light-dark(#d70015, #ff6961);
  --c-orange-ink: light-dark(#b83000, #ffb340);
  --c-yellow-ink: light-dark(#8f5100, #ffd426);
  --c-green-ink: light-dark(#1f7a36, #30db5b);
  --c-mint-ink: light-dark(#0a716c, #66d4cf);
  --c-teal-ink: light-dark(#00748a, #5de6ff);
  --c-cyan-ink: light-dark(#00668f, #70d7ff);
  --c-brown-ink: light-dark(#735a3c, #c4a77f);
  --c-gray-ink: light-dark(#636366, #aeaeb2);

  /* Surfaces */
  --bg: light-dark(#f5f5f7, #000000); /* page canvas */
  --bg-sidebar: light-dark(#fbfbfd, #0f0f10); /* app chrome (sidebar) */
  --surface: light-dark(#ffffff, #1c1c1e); /* cards, panels, inputs on canvas */
  --surface-2: light-dark(#f9f9fb, #242426); /* subtle raised: table header, hovered rows in cards */
  --surface-sunken: light-dark(#efeff2, #0d0d0e); /* wells: board columns, code blocks */
  --surface-elevated: light-dark(#ffffff, #1c1c1e); /* modals, drawers */
  --surface-overlay: light-dark(rgb(255 255 255 / 0.86), rgb(44 44 46 / 0.86)); /* menus (glass) */
  --surface-inverse: light-dark(#1d1d1f, #f5f5f7);

  /* Text */
  --text: light-dark(#1d1d1f, #f5f5f7);
  --text-2: light-dark(#6e6e73, #98989d); /* secondary */
  --text-3: light-dark(#86868b, #7c7c82); /* tertiary: placeholders, meta */
  --text-inverse: light-dark(#ffffff, #1d1d1f);
  --text-on-accent: #ffffff;

  /* Lines & fills (translucent, so they work on any surface) */
  --line: light-dark(rgb(0 0 0 / 0.08), rgb(255 255 255 / 0.09));
  --line-strong: light-dark(rgb(0 0 0 / 0.14), rgb(255 255 255 / 0.16));
  --fill-1: light-dark(rgb(120 120 128 / 0.07), rgb(120 120 128 / 0.16)); /* hover */
  --fill-2: light-dark(rgb(120 120 128 / 0.12), rgb(120 120 128 / 0.24)); /* selected / pressed */
  --fill-3: light-dark(rgb(120 120 128 / 0.2), rgb(120 120 128 / 0.32)); /* tracks, thumbs */
  --card-ring: light-dark(rgb(0 0 0 / 0.05), rgb(255 255 255 / 0.07));

  /* Accent (Apple blue) & semantic colors */
  --accent: light-dark(#0071e3, #0a84ff);
  --accent-hover: light-dark(#0077ed, #2f93ff);
  --accent-pressed: light-dark(#0068d1, #0a7aeb);
  --accent-ink: light-dark(#0066cc, #3d9dff); /* links, tinted text */
  --accent-soft: color-mix(in srgb, var(--accent) 12%, transparent);
  --accent-softer: color-mix(in srgb, var(--accent) 7%, transparent);
  --focus-ring: color-mix(in srgb, var(--accent) 42%, transparent);
  --success: var(--c-green);
  --success-ink: var(--c-green-ink);
  --warning: var(--c-orange);
  --warning-ink: var(--c-orange-ink);
  --danger: var(--c-red);
  --danger-ink: var(--c-red-ink);
  --info: var(--c-blue);
  --info-ink: var(--c-blue-ink);

  /* Materials */
  --glass-bg: light-dark(rgb(255 255 255 / 0.72), rgb(22 22 24 / 0.72));
  --glass-bg-strong: light-dark(rgb(255 255 255 / 0.86), rgb(28 28 30 / 0.86));
  --glass-filter: saturate(180%) blur(20px);
  --glass-line: light-dark(rgb(0 0 0 / 0.08), rgb(255 255 255 / 0.08));
  --scrim: light-dark(rgb(0 0 0 / 0.28), rgb(0 0 0 / 0.56));
  --tooltip-bg: light-dark(rgb(29 29 31 / 0.94), rgb(229 229 234 / 0.96));
  --tooltip-fg: light-dark(#ffffff, #1d1d1f);

  /* Elevation (soft, layered) */
  --shadow-xs: 0 1px 1px light-dark(rgb(0 0 0 / 0.04), rgb(0 0 0 / 0.4));
  --shadow-sm: 0 1px 2px light-dark(rgb(0 0 0 / 0.05), rgb(0 0 0 / 0.42)),
    0 1px 4px light-dark(rgb(0 0 0 / 0.03), rgb(0 0 0 / 0.2));
  --shadow-md: 0 2px 6px light-dark(rgb(0 0 0 / 0.05), rgb(0 0 0 / 0.4)),
    0 8px 24px light-dark(rgb(0 0 0 / 0.07), rgb(0 0 0 / 0.42));
  --shadow-lg: 0 4px 12px light-dark(rgb(0 0 0 / 0.06), rgb(0 0 0 / 0.45)),
    0 18px 48px light-dark(rgb(0 0 0 / 0.12), rgb(0 0 0 / 0.55));
  --shadow-xl: 0 8px 24px light-dark(rgb(0 0 0 / 0.08), rgb(0 0 0 / 0.5)),
    0 32px 80px light-dark(rgb(0 0 0 / 0.2), rgb(0 0 0 / 0.66));

  /* Radii */
  --radius-xs: 6px;
  --radius-sm: 8px;
  --radius-md: 10px;
  --radius-lg: 14px;
  --radius-xl: 20px;
  --radius-2xl: 28px;
  --radius-full: 999px;

  /* Spacing (4px grid) */
  --space-0-5: 0.125rem;
  --space-1: 0.25rem;
  --space-1-5: 0.375rem;
  --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;

  /* Typography */
  --font-sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "InterVariable", "Inter",
    "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-display: "SF Pro Display", -apple-system, BlinkMacSystemFont, "InterVariable", "Inter",
    "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  --fs-2xs: 0.6875rem; /* 11 */
  --fs-xs: 0.75rem; /* 12 */
  --fs-sm: 0.8125rem; /* 13 */
  --fs-md: 0.875rem; /* 14 — UI default */
  --fs-lg: 0.9375rem; /* 15 */
  --fs-xl: 1.0625rem; /* 17 */
  --fs-title-3: 1.25rem; /* 20 */
  --fs-title-2: 1.5rem; /* 24 */
  --fs-title-1: 1.75rem; /* 28 */
  --fs-large: 2.125rem; /* 34 */
  --fs-display: clamp(2.5rem, 1.5rem + 3.6vw, 4rem);
  --fs-body: var(--fs-md);
  --lh-tight: 1.15;
  --lh-snug: 1.3;
  --lh-normal: 1.45;
  --tracking-tight: -0.022em; /* large titles */
  --tracking-snug: -0.012em; /* titles 17–24px */
  --fw-regular: 400;
  --fw-medium: 500;
  --fw-semibold: 600;
  --fw-bold: 700;

  /* Motion */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --ease-sheet: cubic-bezier(0.32, 0.72, 0, 1);
  --dur-1: 120ms;
  --dur-2: 200ms;
  --dur-3: 320ms;
  --dur-4: 480ms;

  /* Layers */
  --z-raised: 2;
  --z-sticky: 20;
  --z-sidebar: 40;
  --z-tabbar: 45;
  --z-scrim: 39;
  --z-overlay: 60;
  --z-tooltip: 90;
  --z-progress: 100;

  /* Layout */
  --sidebar-w: 264px;
  --rail-w: 68px;
  --topbar-h: 52px;
  --tabbar-h: 52px;
  --page-pad-x: 16px;
  --page-pad-y: 20px;
  --content-max: 1200px;
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);

  /* Controls (bigger hit targets on touch, see below) */
  --control-h: 34px;
  --control-h-sm: 28px;
  --control-h-lg: 44px;
  --row-h: 32px; /* nav items, menu items */
  --icon-stroke: 2;

  /* Small glyph masks (use with `mask: var(--check-mask) center / contain no-repeat` + background) */
  --check-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
  --chevron-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E");
  --chevron-left-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m15 18-6-6 6-6'/%3E%3C/svg%3E");

  /* Default tone (overridden by data-color) */
  --tone: var(--c-gray);
  --tone-solid: #8e8e93;
  --tone-ink: var(--c-gray-ink);
  --tone-soft: color-mix(in srgb, var(--tone) 14%, transparent);
  --tone-softer: color-mix(in srgb, var(--tone) 8%, transparent);
  --tone-line: color-mix(in srgb, var(--tone) 32%, transparent);
  --tone-on: #ffffff;
}

:root[data-theme="light"] {
  color-scheme: light;
}
:root[data-theme="dark"] {
  color-scheme: dark;
}

@media (pointer: coarse) {
  :root {
    --control-h: 40px;
    --control-h-sm: 34px;
    --control-h-lg: 48px;
    --row-h: 40px;
  }
}
@media (max-width: 767px) {
  :root {
    --fs-body: var(--fs-lg);
    --topbar-h: 48px;
  }
}
@media (min-width: 768px) {
  :root {
    --page-pad-x: 24px;
    --page-pad-y: 24px;
  }
}
@media (min-width: 1280px) {
  :root {
    --page-pad-x: 32px;
    --page-pad-y: 28px;
  }
}

/* Reduced motion: every token-driven transition becomes (almost) instant. Non-essential keyframe
   animations are additionally declared only inside `prefers-reduced-motion: no-preference`. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-1: 1ms;
    --dur-2: 1ms;
    --dur-3: 1ms;
    --dur-4: 1ms;
    --ease-spring: linear;
  }
}

/* --------------------------------------------------------------------------------------------------
   3. Color tones — any element with data-color="<palette name>" sets --tone (vivid), --tone-ink
      (readable text), --tone-soft / --tone-softer (tinted backgrounds), --tone-line (borders) and
      --tone-solid (saturated fill that keeps its light-mode value in dark mode — avatars, icon tiles,
      solid chips with white text, like iOS) and --tone-on (text on a solid tone). Components read
      these variables.
   -------------------------------------------------------------------------------------------------- */
[data-color="blue"] { --tone: var(--c-blue); --tone-ink: var(--c-blue-ink); --tone-solid: #007aff; }
[data-color="indigo"] { --tone: var(--c-indigo); --tone-ink: var(--c-indigo-ink); --tone-solid: #5856d6; }
[data-color="purple"] { --tone: var(--c-purple); --tone-ink: var(--c-purple-ink); --tone-solid: #af52de; }
[data-color="pink"] { --tone: var(--c-pink); --tone-ink: var(--c-pink-ink); --tone-solid: #ff2d55; }
[data-color="red"] { --tone: var(--c-red); --tone-ink: var(--c-red-ink); --tone-solid: #ff3b30; }
[data-color="orange"] { --tone: var(--c-orange); --tone-ink: var(--c-orange-ink); --tone-solid: #ff9500; }
[data-color="yellow"] { --tone: var(--c-yellow); --tone-ink: var(--c-yellow-ink); --tone-solid: #ffcc00; }
[data-color="green"] { --tone: var(--c-green); --tone-ink: var(--c-green-ink); --tone-solid: #34c759; }
[data-color="mint"] { --tone: var(--c-mint); --tone-ink: var(--c-mint-ink); --tone-solid: #00c7be; }
[data-color="teal"] { --tone: var(--c-teal); --tone-ink: var(--c-teal-ink); --tone-solid: #30b0c7; }
[data-color="cyan"] { --tone: var(--c-cyan); --tone-ink: var(--c-cyan-ink); --tone-solid: #32ade6; }
[data-color="brown"] { --tone: var(--c-brown); --tone-ink: var(--c-brown-ink); --tone-solid: #a2845e; }
[data-color="gray"] { --tone: var(--c-gray); --tone-ink: var(--c-gray-ink); --tone-solid: #8e8e93; }
[data-color="accent"] { --tone: var(--accent); --tone-ink: var(--accent-ink); --tone-solid: #0071e3; }
[data-color] {
  --tone-soft: color-mix(in srgb, var(--tone) 14%, transparent);
  --tone-softer: color-mix(in srgb, var(--tone) 8%, transparent);
  --tone-line: color-mix(in srgb, var(--tone) 32%, transparent);
  --tone-on: #ffffff;
}
[data-color="yellow"],
[data-color="mint"] {
  --tone-on: rgb(0 0 0 / 0.78);
}

/* --------------------------------------------------------------------------------------------------
   4. Reset & base elements
   -------------------------------------------------------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
  tab-size: 4;
  scroll-padding-top: calc(var(--topbar-h) + var(--safe-top) + 16px);
  scrollbar-color: var(--fill-3) transparent;
  hanging-punctuation: first last;
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: var(--lh-normal);
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-wrap: break-word;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-snug);
  text-wrap: balance;
}
p,
ul,
ol,
dl,
dd,
figure,
blockquote,
pre {
  margin: 0;
}
ul[role="list"],
ol[role="list"],
ul.plain,
ol.plain {
  list-style: none;
  padding: 0;
}
p {
  text-wrap: pretty;
}

a {
  color: inherit;
  text-decoration: none;
}
img,
video,
canvas,
picture {
  display: block;
  max-width: 100%;
}
img {
  height: auto;
}
svg {
  flex-shrink: 0;
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
}
button {
  cursor: pointer;
}
button:disabled {
  cursor: not-allowed;
}
input,
select,
textarea {
  margin: 0;
}
table {
  border-collapse: collapse;
}
hr {
  height: 0;
  margin: var(--space-4) 0;
  border: 0;
  border-top: 1px solid var(--line);
}
code,
kbd,
samp,
pre {
  font-family: var(--font-mono);
  font-size: 0.92em;
}
abbr[title] {
  text-decoration: underline dotted;
  cursor: help;
}
[hidden] {
  display: none !important;
}
[x-cloak] {
  display: none !important;
}
dialog {
  color: inherit;
}

::selection {
  background: color-mix(in srgb, var(--accent) 24%, transparent);
}

/* Focus: visible, soft accent glow (keyboard only). */
:focus {
  outline: none;
}
:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--accent) 80%, transparent);
  outline-offset: 2px;
}

/* Thin, subtle scrollbars for inner scroll containers (overlay scrollbars on macOS/iOS anyway). */
* {
  scrollbar-width: thin;
}

/* Links in running text */
.link,
.prose a {
  color: var(--accent-ink);
  text-decoration: none;
  border-radius: 2px;
}
.link:hover,
.prose a:hover {
  text-decoration: underline;
  text-underline-offset: 0.18em;
}

/* --------------------------------------------------------------------------------------------------
   5. Typography helpers
   -------------------------------------------------------------------------------------------------- */
.display {
  font-family: var(--font-display);
  font-size: var(--fs-display);
  font-weight: var(--fw-bold);
  line-height: 1.05;
  letter-spacing: -0.03em;
}
.large-title {
  font-family: var(--font-display);
  font-size: var(--fs-large);
  font-weight: var(--fw-bold);
  line-height: var(--lh-tight);
  letter-spacing: var(--tracking-tight);
}
.title-1 {
  font-family: var(--font-display);
  font-size: var(--fs-title-1);
  font-weight: var(--fw-bold);
  line-height: var(--lh-tight);
  letter-spacing: var(--tracking-tight);
}
.title-2 {
  font-family: var(--font-display);
  font-size: var(--fs-title-2);
  font-weight: var(--fw-semibold);
  line-height: 1.2;
  letter-spacing: var(--tracking-tight);
}
.title-3 {
  font-size: var(--fs-title-3);
  font-weight: var(--fw-semibold);
  line-height: 1.25;
  letter-spacing: var(--tracking-snug);
}
.headline {
  font-size: var(--fs-xl);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-snug);
}
.subhead {
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
}
.eyebrow {
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  letter-spacing: 0.02em;
  color: var(--text-2);
}
.text-2xs { font-size: var(--fs-2xs); }
.text-xs { font-size: var(--fs-xs); }
.text-sm { font-size: var(--fs-sm); }
.text-md { font-size: var(--fs-md); }
.text-lg { font-size: var(--fs-lg); }
.text-xl { font-size: var(--fs-xl); }
.text-2 { color: var(--text-2); }
.text-3 { color: var(--text-3); }
.text-accent { color: var(--accent-ink); }
.text-danger { color: var(--danger-ink); }
.text-success { color: var(--success-ink); }
.text-tone { color: var(--tone-ink); }
.fw-medium { font-weight: var(--fw-medium); }
.fw-semibold { font-weight: var(--fw-semibold); }
.fw-bold { font-weight: var(--fw-bold); }
.tabular { font-variant-numeric: tabular-nums; }
.mono { font-family: var(--font-mono); }
.nowrap { white-space: nowrap; }
.truncate {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.line-clamp-2,
.line-clamp-3 {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}
.line-clamp-3 {
  -webkit-line-clamp: 3;
  line-clamp: 3;
}

/* Rich text (markdown output) */
.prose {
  font-size: var(--fs-md);
  line-height: 1.6;
  overflow-wrap: anywhere;
}
.prose > * + * {
  margin-top: 0.75em;
}
.prose h1,
.prose h2,
.prose h3 {
  margin-top: 1.25em;
  font-size: var(--fs-xl);
}
.prose ul,
.prose ol {
  padding-left: 1.4em;
}
.prose li + li {
  margin-top: 0.25em;
}
.prose blockquote {
  padding-left: var(--space-3);
  border-left: 3px solid var(--line-strong);
  color: var(--text-2);
}
.prose code {
  padding: 0.1em 0.35em;
  border-radius: 5px;
  background: var(--fill-1);
}
.prose pre {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--surface-sunken);
  overflow-x: auto;
}
.prose pre code {
  padding: 0;
  background: none;
}
.prose img {
  border-radius: var(--radius-md);
}
.prose .mention {
  padding: 0 0.25em;
  border-radius: 5px;
  background: var(--accent-soft);
  color: var(--accent-ink);
  font-weight: var(--fw-medium);
}

/* --------------------------------------------------------------------------------------------------
   6. Icons — {% icon "name" size=16 %} renders <svg class="icon"><use href="sprite#name"/></svg>.
      Color = currentColor. Stroke width: --icon-stroke (default 2, in 24-unit space).
   -------------------------------------------------------------------------------------------------- */
.icon {
  display: inline-block;
  flex-shrink: 0;
  vertical-align: middle;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.icon--thin {
  --icon-stroke: 1.6;
}
.icon--bold {
  --icon-stroke: 2.4;
}
.icon.spin {
  animation: spin 0.9s linear infinite;
}

/* --------------------------------------------------------------------------------------------------
   7. Layout utilities (small, composable — prefer components for anything bigger)
   -------------------------------------------------------------------------------------------------- */
.stack {
  display: flex;
  flex-direction: column;
  gap: var(--stack-gap, var(--space-3));
}
.stack-xs { --stack-gap: var(--space-1); }
.stack-sm { --stack-gap: var(--space-2); }
.stack-lg { --stack-gap: var(--space-5); }
.stack-xl { --stack-gap: var(--space-8); }
.cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--cluster-gap, var(--space-2));
}
.row {
  display: flex;
  align-items: center;
  gap: var(--row-gap, var(--space-2));
  min-width: 0;
}
.row--between { justify-content: space-between; }
.row--end { justify-content: flex-end; }
.row--top { align-items: flex-start; }
.spacer { flex: 1 1 auto; }
.grow { flex: 1 1 auto; min-width: 0; }
.shrink-0 { flex-shrink: 0; }
.grid-auto {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(var(--grid-min, 260px), 100%), 1fr));
  gap: var(--grid-gap, var(--space-4));
}
.container {
  width: 100%;
  max-width: var(--content-max);
  margin-inline: auto;
}
.container--narrow { --content-max: 760px; }
.container--medium { --content-max: 960px; }
.container--wide { --content-max: 1440px; }
.w-full { width: 100%; }
.mt-0 { margin-top: 0; }
.mt-1 { margin-top: var(--space-1); }
.mt-2 { margin-top: var(--space-2); }
.mt-3 { margin-top: var(--space-3); }
.mt-4 { margin-top: var(--space-4); }
.mt-6 { margin-top: var(--space-6); }
.mt-8 { margin-top: var(--space-8); }
.mb-2 { margin-bottom: var(--space-2); }
.mb-4 { margin-bottom: var(--space-4); }
.mb-6 { margin-bottom: var(--space-6); }
.gap-1 { gap: var(--space-1); }
.gap-2 { gap: var(--space-2); }
.gap-3 { gap: var(--space-3); }
.gap-4 { gap: var(--space-4); }
.gap-6 { gap: var(--space-6); }

.sr-only,
.visually-hidden {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  margin: -1px !important;
  padding: 0 !important;
  overflow: hidden !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

/* Responsive visibility */
@media (max-width: 639px) {
  .hide-xs { display: none !important; }
}
@media (max-width: 767px) {
  .hide-mobile { display: none !important; }
}
@media (min-width: 768px) {
  .only-mobile { display: none !important; }
}
@media (max-width: 1023px) {
  .only-desktop { display: none !important; }
}
@media (min-width: 1024px) {
  .hide-desktop { display: none !important; }
}

/* Platform-aware modifier key: <span class="mod-key"></span>K → ⌘K on Apple, Ctrl K elsewhere. */
.mod-key::before {
  content: "Ctrl\00a0";
}
:root.is-apple .mod-key::before {
  content: "\2318";
}

/* --------------------------------------------------------------------------------------------------
   8. Motion — keyframes, scroll reveal, page (view) transitions
   -------------------------------------------------------------------------------------------------- */
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
@keyframes fade-in {
  from {
    opacity: 0;
  }
}
@keyframes fade-up {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
}
@keyframes pop {
  0% {
    transform: scale(1);
  }
  40% {
    transform: scale(1.18);
  }
  100% {
    transform: scale(1);
  }
}
@keyframes shimmer {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(100%);
  }
}

/* Scroll reveal: [data-reveal] fades/slides in once visible (app.js adds .is-revealed and staggers
   siblings through --reveal-delay). Content is never hidden without JS (base.html drops
   .js-reveal if app.js did not start) or with reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  :root.js-reveal [data-reveal]:not(.is-revealed) {
    opacity: 0;
    transform: translateY(12px);
  }
  :root.js-reveal [data-reveal] {
    transition:
      opacity var(--dur-4) var(--ease-out) var(--reveal-delay, 0ms),
      transform var(--dur-4) var(--ease-out) var(--reveal-delay, 0ms);
  }
}

/* Cross-document page transitions (Chrome/Edge/Safari 18+). Named parts of the app shell
   (view-transition-name: sidebar, tabbar — see shell.css) stay put; the page content (`page`)
   fades out quickly and the new one rises in; the project view-tab indicator morphs between tabs.
   Names must be unique per page — do not reuse these names in feature CSS. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
  }
  ::view-transition-group(root) {
    animation-duration: 220ms;
  }
  ::view-transition-old(page) {
    animation: 120ms var(--ease-out) both vt-fade-out;
  }
  ::view-transition-new(page) {
    animation: 300ms var(--ease-out) 60ms both vt-rise-in;
  }
  ::view-transition-group(view-tab-indicator) {
    animation-duration: 380ms;
    animation-timing-function: var(--ease-spring);
  }
}
/* Theme switch (same-document view transition started by App.theme.set): plain cross-fade. */
:root.vt-theme::view-transition-old(*),
:root.vt-theme::view-transition-new(*) {
  animation-duration: 280ms;
  animation-delay: 0s;
  animation-timing-function: ease;
}
:root.vt-theme::view-transition-new(page) {
  animation-name: vt-fade-in;
}
@keyframes vt-fade-in {
  from {
    opacity: 0;
  }
}
@keyframes vt-fade-out {
  to {
    opacity: 0;
  }
}
@keyframes vt-rise-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
}
