/* ==========================================================================
   Lynkly design tokens
   --------------------------------------------------------------------------
   Typeface: IBM Plex Sans and IBM Plex Mono, SIL Open Font License 1.1,
   served from assets/fonts. Nothing here reaches out to Google Fonts, and the
   Content-Security-Policy would refuse it if it tried.

   Plex reads like the instrument panel of a piece of infrastructure, which is
   what a self-hosted tool is. Mono is not decoration: it carries version
   numbers, schema versions, hashes and file counts, where digits lining up
   column to column is information.

   Colour: cool graphite neutrals. The one loud colour on any page belongs to
   the operator, injected at runtime from the settings as --accent, so the
   scaffolding stays quiet enough to let it be the loud thing.

   Radius rule, applied everywhere without exception:
     inputs and small controls  8px
     buttons and link rows     12px
     panels and cards          16px
     avatar                    24px
   ========================================================================== */

/* Latin1 covers German, Latin2 covers the rest of Central Europe. Anything
   outside both falls through to the system stack, which is why the fallback
   list is written out rather than left to chance. */

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/IBMPlexSans-Regular-Latin1.woff2') format('woff2');
  unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-00FF, U+0131, U+0152-0153,
    U+02C6, U+02DA, U+02DC, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022,
    U+2026, U+2030, U+2039-203A, U+2044, U+20AC, U+2122, U+2212, U+FB01-FB02;
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/IBMPlexSans-Regular-Latin2.woff2') format('woff2');
  unicode-range: U+0100-0130, U+0132-0151, U+0154-017F, U+0218-021B, U+02C7,
    U+02D8-02D9, U+02DB, U+02DD, U+2C7E-2C7F;
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/IBMPlexSans-Medium-Latin1.woff2') format('woff2');
  unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-00FF, U+0131, U+0152-0153,
    U+02C6, U+02DA, U+02DC, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022,
    U+2026, U+2030, U+2039-203A, U+2044, U+20AC, U+2122, U+2212, U+FB01-FB02;
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/IBMPlexSans-Medium-Latin2.woff2') format('woff2');
  unicode-range: U+0100-0130, U+0132-0151, U+0154-017F, U+0218-021B, U+02C7,
    U+02D8-02D9, U+02DB, U+02DD, U+2C7E-2C7F;
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../fonts/IBMPlexSans-SemiBold-Latin1.woff2') format('woff2');
  unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-00FF, U+0131, U+0152-0153,
    U+02C6, U+02DA, U+02DC, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022,
    U+2026, U+2030, U+2039-203A, U+2044, U+20AC, U+2122, U+2212, U+FB01-FB02;
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../fonts/IBMPlexSans-SemiBold-Latin2.woff2') format('woff2');
  unicode-range: U+0100-0130, U+0132-0151, U+0154-017F, U+0218-021B, U+02C7,
    U+02D8-02D9, U+02DB, U+02DD, U+2C7E-2C7F;
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/IBMPlexMono-Regular-Latin1.woff2') format('woff2');
  unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-00FF, U+2013-2014,
    U+2018-201A, U+201C-201E, U+2020-2022, U+2026, U+20AC, U+2122;
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/IBMPlexMono-Medium-Latin1.woff2') format('woff2');
  unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-00FF, U+2013-2014,
    U+2018-201A, U+201C-201E, U+2020-2022, U+2026, U+20AC, U+2122;
}

:root {
  --font-sans: 'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', Roboto,
    'Helvetica Neue', Arial, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, 'SFMono-Regular', Menlo, Consolas,
    monospace;

  --bg: #f4f6f8;
  --bg-rgb: 244, 246, 248;
  --surface: #ffffff;
  --surface-2: #eaeef2;
  --border: #dbe1e8;
  --border-strong: #bcc6d1;
  --text: #12161c;
  --text-muted: #5a6572;
  --text-faint: #838d9a;

  --danger: #b3261e;
  --danger-soft: rgba(179, 38, 30, 0.1);
  --success: #14663f;
  --success-soft: rgba(20, 102, 63, 0.1);
  --warning: #8a5a00;
  --warning-soft: rgba(138, 90, 0, 0.12);

  --accent: #2f6fed;
  --accent-contrast: #ffffff;
  --accent-soft: rgba(47, 111, 237, 0.12);
  --accent-line: rgba(47, 111, 237, 0.35);

  --r-input: 8px;
  --r-control: 12px;
  --r-panel: 16px;
  --r-avatar: 24px;

  --shadow-sm: 0 1px 2px rgba(18, 22, 28, 0.06);
  --shadow-md: 0 6px 20px -8px rgba(18, 22, 28, 0.22);

  --speed: 160ms;
  --ease: cubic-bezier(0.2, 0, 0.15, 1);

  color-scheme: light;
}

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

@media (prefers-color-scheme: dark) {
  :root[data-theme='auto'] {
    color-scheme: dark;
  }
}

/* Dark values live in one place and are switched on by either the explicit
   attribute or the media query, so the two never drift apart. */
:root[data-theme='dark'] {
  --bg: #0f1216;
  --bg-rgb: 15, 18, 22;
  --surface: #161a20;
  --surface-2: #1e232b;
  --border: #272d37;
  --border-strong: #3a434f;
  --text: #e6eaef;
  --text-muted: #98a2af;
  --text-faint: #79838f;
  --danger: #f28b82;
  --danger-soft: rgba(242, 139, 130, 0.14);
  --success: #6cd39a;
  --success-soft: rgba(108, 211, 154, 0.14);
  --warning: #e0b25c;
  --warning-soft: rgba(224, 178, 92, 0.14);
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 8px 24px -10px rgba(0, 0, 0, 0.7);
}

@media (prefers-color-scheme: dark) {
  :root[data-theme='auto'] {
    --bg: #0f1216;
    --bg-rgb: 15, 18, 22;
    --surface: #161a20;
    --surface-2: #1e232b;
    --border: #272d37;
    --border-strong: #3a434f;
    --text: #e6eaef;
    --text-muted: #98a2af;
    --text-faint: #79838f;
    --danger: #f28b82;
    --danger-soft: rgba(242, 139, 130, 0.14);
    --success: #6cd39a;
    --success-soft: rgba(108, 211, 154, 0.14);
    --warning: #e0b25c;
    --warning-soft: rgba(224, 178, 92, 0.14);
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 8px 24px -10px rgba(0, 0, 0, 0.7);
  }
}

/* --------------------------------------------------------------- baseline */

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
  margin: 0;
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.25;
}

p {
  margin: 0;
}

a {
  color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}

img {
  max-width: 100%;
  display: block;
}

/*
 * An inline SVG sits on the text baseline, and the descender space below it
 * stays inside the line box. Anything centring that line box centres the box
 * rather than the drawing, so the icon lands half a descender too high.
 * Measured on the public page: every chevron sat exactly five pixels above the
 * middle of its button.
 *
 * `vertical-align: middle` rather than `display: block`, because some icons
 * genuinely belong in a line of text — the arrow between an old and a new value
 * in the activity log would otherwise break onto a line of its own. Icons that
 * sit alone in a box are centred by that box instead; see .link__arrow.
 */
svg {
  vertical-align: middle;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

.mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

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

.skip-link {
  position: absolute;
  left: 8px;
  top: -60px;
  z-index: 100;
  padding: 10px 16px;
  border-radius: var(--r-control);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-md);
  transition: top var(--speed) var(--ease);
}

.skip-link:focus {
  top: 8px;
}

/* ----------------------------------------------------------------- controls */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 42px;
  padding: 0 18px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-control);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--speed) var(--ease), border-color var(--speed) var(--ease),
    transform var(--speed) var(--ease);
}

.btn:hover {
  background: var(--surface-2);
}

.btn:active {
  transform: translateY(1px);
}

.btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-contrast);
}

.btn--primary:hover {
  background: var(--accent);
  filter: brightness(1.08);
}

.btn--danger {
  color: var(--danger);
  border-color: var(--border-strong);
}

.btn--danger:hover {
  background: var(--danger-soft);
  border-color: var(--danger);
}

.btn--quiet {
  border-color: transparent;
  background: transparent;
  color: var(--text-muted);
}

.btn--quiet:hover {
  background: var(--surface-2);
  color: var(--text);
}

.btn--small {
  min-height: 34px;
  padding: 0 12px;
  font-size: 0.8125rem;
}

.btn[disabled],
.btn[aria-disabled='true'] {
  opacity: 0.5;
  pointer-events: none;
}

.btn svg {
  flex: none;
}

/* -------------------------------------------------------------------- forms */

.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 20px;
}

.field > label {
  font-weight: 500;
  font-size: 0.875rem;
}

.field__hint {
  font-size: 0.8125rem;
  color: var(--text-muted);
}

.field__error {
  font-size: 0.8125rem;
  color: var(--danger);
}

input[type='text'],
input[type='url'],
input[type='email'],
input[type='password'],
input[type='number'],
input[type='search'],
select,
textarea {
  width: 100%;
  min-height: 42px;
  padding: 9px 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-input);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  transition: border-color var(--speed) var(--ease), box-shadow var(--speed) var(--ease);
}

textarea {
  min-height: 96px;
  resize: vertical;
}

input:focus,
select:focus,
textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

input::placeholder,
textarea::placeholder {
  color: var(--text-faint);
}

input[type='color'] {
  width: 56px;
  min-height: 42px;
  padding: 4px;
  cursor: pointer;
}

input[type='file'] {
  width: 100%;
  padding: 9px 12px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-input);
  background: var(--surface-2);
  font-size: 0.875rem;
}

.switch {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--r-input);
  background: var(--surface);
  cursor: pointer;
}

.switch input {
  margin: 3px 0 0;
  width: 18px;
  height: 18px;
  accent-color: var(--accent);
  flex: none;
}

.switch__text {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.switch__text strong {
  font-weight: 500;
}

.switch__text span {
  font-size: 0.8125rem;
  color: var(--text-muted);
}

/* ------------------------------------------------------------------ notices */

.notice {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 12px 14px;
  margin-bottom: 20px;
  border: 1px solid var(--border);
  border-left-width: 3px;
  border-radius: var(--r-input);
  background: var(--surface);
  font-size: 0.875rem;
}

.notice svg {
  flex: none;
  margin-top: 2px;
}

.notice--success {
  border-left-color: var(--success);
  background: var(--success-soft);
  color: var(--success);
}

.notice--error {
  border-left-color: var(--danger);
  background: var(--danger-soft);
  color: var(--danger);
}

.notice--warning {
  border-left-color: var(--warning);
  background: var(--warning-soft);
  color: var(--warning);
}

.notice--info {
  border-left-color: var(--accent);
  background: var(--accent-soft);
  color: var(--text);
}

@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;
  }
}
